From 58bfaf0e36785c876988c3111643a150c73234c5 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Sep 2024 15:06:58 +0200 Subject: [PATCH 001/659] airlock sync (#1) * airlock sync * empty commit --- .github/workflows/ci.yml | 2 +- README.md | 2 +- ...sqlserver-source-repro-pipeline-example.sh | 4 +- ccloud/audit-log-connector/README.md | 8 +- ccloud/audit-log-connector/start.sh | 4 +- .../replicator-onprem-to-cloud.sh | 4 +- ccloud/environment/docker-compose.yml | 2 +- .../fully-managed-azure-functions-sink.sh | 4 +- ccloud/fm-azure-functions-sink/stop.sh | 2 +- ...ully-managed-databricks-delta-lake-sink.sh | 15 +- ccloud/fm-datagen-source/README.md | 11 + .../fully-managed-datagen-source.sh | 38 ++++ ccloud/fm-datagen-source/stop.sh | 8 + ...ed-debezium-legacy-sqlserver-source-ssl.sh | 4 +- ...anaged-debezium-legacy-sqlserver-source.sh | 4 +- ...anaged-debezium-v2-sqlserver-source-ssl.sh | 4 +- ...ly-managed-debezium-v2-sqlserver-source.sh | 4 +- .../fully-managed-sqlserver-microsoft-sink.sh | 2 +- .../fully-managed-sqlserver-source.sh | 4 +- cloudformation/kafka-docker-playground.yml | 2 + .../azure-functions-sink.sh | 2 +- .../azure-service-bus-source.sh | 2 + .../README.md | 4 +- ...m-sqlserver-source-incremental-snapshot.sh | 12 +- .../debezium-sqlserver-source-ssl.sh | 4 +- ...zium-sqlserver-source-standalone-worker.sh | 4 +- .../debezium-sqlserver-source.sh | 4 +- .../docker-compose.plaintext.yml | 1 + .../gcp-google-pubsub-sink.sh | 5 + .../docker-compose.plaintext.yml | 1 + .../gcp-google-pubsub-source.sh | 5 + .../docker-compose.plaintext.kerberos.yml | 2 + .../docker-compose.plaintext.yml | 2 + .../docker-compose.plaintext.yml | 2 + .../docker-compose.plaintext.yml | 2 + .../docker-compose.plaintext.yml | 2 + connect/connect-http-sink/http_no_auth.sh | 3 +- .../connect-http-sink/httpserver/server.js | 20 +- connect/connect-iceberg-sink/spark/Dockerfile | 2 +- connect/connect-jdbc-sqlserver-sink/README.md | 2 +- .../sqlserver-jtds-sink-ssl.sh | 2 +- .../sqlserver-jtds-sink.sh | 2 +- .../sqlserver-microsoft-sink-ssl.sh | 2 +- .../sqlserver-microsoft-sink.sh | 2 +- .../connect-jdbc-sqlserver-source/README.md | 4 +- .../sqlserver-jtds-ssl.sh | 4 +- .../sqlserver-jtds.sh | 4 +- .../sqlserver-microsoft-ssl.sh | 4 +- .../sqlserver-microsoft.sh | 4 +- .../docker-compose.plaintext.yml | 2 + .../docker-compose.plaintext.yml | 2 + connect/connect-mapr-sink/mapr-sink.sh | 4 +- .../docker-compose.plaintext.yml | 2 + docs/content-template.md | 1 + .../rbac-sasl-plain/docker-compose.yml | 6 +- .../scripts/helper/create-role-bindings.sh | 21 ++ scripts/cli/completions.bash | 2 +- scripts/cli/confluent-hub-plugin-list.txt | 6 +- scripts/cli/confluent-kafka-region-list.txt | 188 +++++++++--------- scripts/cli/playground.json | 16 +- scripts/cli/playground.yaml | 14 ++ scripts/cli/tag-list.txt | 16 +- scripts/utils.sh | 2 +- 63 files changed, 347 insertions(+), 172 deletions(-) create mode 100644 ccloud/fm-datagen-source/README.md create mode 100755 ccloud/fm-datagen-source/fully-managed-datagen-source.sh create mode 100755 ccloud/fm-datagen-source/stop.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e7be12dff4..2edda96d82 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,7 +102,7 @@ jobs: "🚀 ccloud/fm-aws-kinesis-source ccloud/fm-aws-redshift-sink ccloud/fm-aws-sqs-source ccloud/fm-aws-lambda-sink ccloud/fm-azure-blob-storage-sink ccloud/fm-azure-blob-storage-source ccloud/fm-azure-cognitive-search-sink ccloud/fm-mongodb-atlas-source ccloud/fm-mongodb-atlas-sink ccloud/fm-salesforce-bulkapi-source ccloud/fm-salesforce-bulkapi-2-0-source ccloud/custom-connector-connect-aws-s3-sink", - "🚀 ccloud/fm-datadog-metrics-sink ccloud/fm-salesforce-bulkapi-2-0-sink ccloud/fm-salesforce-platform-events-source ccloud/fm-servicenow-source ccloud/fm-servicenow-sink ccloud/fm-aws-dynamodb-cdc-source", + "🚀 ccloud/fm-datadog-metrics-sink ccloud/fm-salesforce-bulkapi-2-0-sink ccloud/fm-salesforce-platform-events-source ccloud/fm-servicenow-source ccloud/fm-servicenow-sink ccloud/fm-aws-dynamodb-cdc-source ccloud/fm-datagen-source", "🚀 connect/connect-servicenow-sink connect/connect-servicenow-source connect/connect-datagen-source", "🚀 connect/connect-salesforce-bulkapi-sink connect/connect-salesforce-bulkapi-source connect/connect-salesforce-pushtopics-source connect/connect-salesforce-sobject-sink connect/connect-salesforce-cdc-source connect/connect-salesforce-platform-events-sink connect/connect-salesforce-platform-events-source", diff --git a/README.md b/README.md index 586c1db615..dbde225375 100644 --- a/README.md +++ b/README.md @@ -45,4 +45,4 @@ Love it? Give it a ⭐️ by clicking below: ## ⭐️ Star History -[![Star History Chart](https://api.star-history.com/svg?repos=vdesabou/kafka-docker-playground&type=Date)](https://star-history.com/#vdesabou/kafka-docker-playground&Date) +[![Star History Chart](https://api.star-history.com/svg?repos=vdesabou/kafka-docker-playground&type=Date)](https://star-history.com/#vdesabou/kafka-docker-playground&Date) \ No newline at end of file diff --git a/academy/connect-connect-debezium-sqlserver-source/debezium-sqlserver-source-repro-pipeline-example.sh b/academy/connect-connect-debezium-sqlserver-source/debezium-sqlserver-source-repro-pipeline-example.sh index c8eb79f362..7dd20d8cd5 100755 --- a/academy/connect-connect-debezium-sqlserver-source/debezium-sqlserver-source-repro-pipeline-example.sh +++ b/academy/connect-connect-debezium-sqlserver-source/debezium-sqlserver-source-repro-pipeline-example.sh @@ -16,7 +16,7 @@ playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker- log "Create table" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -73,7 +73,7 @@ EOF sleep 5 -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/ccloud/audit-log-connector/README.md b/ccloud/audit-log-connector/README.md index 3eefe7ba68..789cfbf42c 100644 --- a/ccloud/audit-log-connector/README.md +++ b/ccloud/audit-log-connector/README.md @@ -38,8 +38,8 @@ playground connector create-or-update --connector filestream-sink << EOF "consumer.override.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/data_audit_cluster:sasl.username}\" password=\"\${file:/data_audit_cluster:sasl.password}\";", "consumer.override.client.dns.lookup": "use_all_dns_ips", "consumer.override.interceptor.classes": "io.confluent.monitoring.clients.interceptor.MonitoringConsumerInterceptor", - "consumer.override.confluent.monitoring.interceptor.bootstrap.servers": "${file:/data:bootstrap.servers}", - "consumer.override.confluent.monitoring.interceptor.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/data:sasl.username}\" password=\"\${file:/data:sasl.password}\";", + "consumer.override.confluent.monitoring.interceptor.bootstrap.servers": "${file:/datacloud:bootstrap.servers}", + "consumer.override.confluent.monitoring.interceptor.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/datacloud:sasl.username}\" password=\"\${file:/datacloud:sasl.password}\";", "consumer.override.confluent.monitoring.interceptor.sasl.mechanism": "PLAIN", "consumer.override.confluent.monitoring.interceptor.security.protocol": "SASL_SSL" } @@ -59,8 +59,8 @@ Note that we also need to override monitoring interceptors to use the confluent ```json "consumer.override.interceptor.classes": "io.confluent.monitoring.clients.interceptor.MonitoringConsumerInterceptor", - "consumer.override.confluent.monitoring.interceptor.bootstrap.servers": "${file:/data:bootstrap.servers}", - "consumer.override.confluent.monitoring.interceptor.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/data:sasl.username}\" password=\"\${file:/data:sasl.password}\";", + "consumer.override.confluent.monitoring.interceptor.bootstrap.servers": "${file:/datacloud:bootstrap.servers}", + "consumer.override.confluent.monitoring.interceptor.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/datacloud:sasl.username}\" password=\"\${file:/datacloud:sasl.password}\";", "consumer.override.confluent.monitoring.interceptor.sasl.mechanism": "PLAIN", "consumer.override.confluent.monitoring.interceptor.security.protocol": "SASL_SSL" ``` diff --git a/ccloud/audit-log-connector/start.sh b/ccloud/audit-log-connector/start.sh index fb9111fc24..2ca6661e9c 100755 --- a/ccloud/audit-log-connector/start.sh +++ b/ccloud/audit-log-connector/start.sh @@ -52,8 +52,8 @@ playground connector create-or-update --connector filestream-sink << EOF "consumer.override.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/data_audit_cluster:sasl.username}\" password=\"\${file:/data_audit_cluster:sasl.password}\";", "consumer.override.client.dns.lookup": "use_all_dns_ips", "consumer.override.interceptor.classes": "io.confluent.monitoring.clients.interceptor.MonitoringConsumerInterceptor", - "consumer.override.confluent.monitoring.interceptor.bootstrap.servers": "\${file:/data:bootstrap.servers}", - "consumer.override.confluent.monitoring.interceptor.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/data:sasl.username}\" password=\"\${file:/data:sasl.password}\";", + "consumer.override.confluent.monitoring.interceptor.bootstrap.servers": "\${file:/datacloud:bootstrap.servers}", + "consumer.override.confluent.monitoring.interceptor.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/datacloud:sasl.username}\" password=\"\${file:/datacloud:sasl.password}\";", "consumer.override.confluent.monitoring.interceptor.sasl.mechanism": "PLAIN", "consumer.override.confluent.monitoring.interceptor.security.protocol": "SASL_SSL" } diff --git a/ccloud/connect-centralized-license/replicator-onprem-to-cloud.sh b/ccloud/connect-centralized-license/replicator-onprem-to-cloud.sh index d1cc938332..e2c53c8548 100755 --- a/ccloud/connect-centralized-license/replicator-onprem-to-cloud.sh +++ b/ccloud/connect-centralized-license/replicator-onprem-to-cloud.sh @@ -35,9 +35,9 @@ playground connector create-or-update --connector replicate-onprem-to-cloud << "src.consumer.group.id": "replicate-onprem-to-cloud", "src.kafka.bootstrap.servers": "broker:9092", "dest.kafka.ssl.endpoint.identification.algorithm":"https", - "dest.kafka.bootstrap.servers": "\${file:/data:bootstrap.servers}", + "dest.kafka.bootstrap.servers": "\${file:/datacloud:bootstrap.servers}", "dest.kafka.security.protocol" : "SASL_SSL", - "dest.kafka.sasl.jaas.config": "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/data:sasl.username}\" password=\"\${file:/data:sasl.password}\";", + "dest.kafka.sasl.jaas.config": "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/datacloud:sasl.username}\" password=\"\${file:/datacloud:sasl.password}\";", "dest.kafka.sasl.mechanism":"PLAIN", "dest.kafka.request.timeout.ms":"20000", "dest.kafka.retry.backoff.ms":"500", diff --git a/ccloud/environment/docker-compose.yml b/ccloud/environment/docker-compose.yml index f969592593..bbc04df1c6 100644 --- a/ccloud/environment/docker-compose.yml +++ b/ccloud/environment/docker-compose.yml @@ -8,7 +8,7 @@ services: - "8083:8083" - "5005:5005" volumes: - - ../../ccloud/environment/data:/data + - ../../ccloud/environment/data:/datacloud - ../../confluent-hub:/usr/share/confluent-hub-components environment: CONNECT_BOOTSTRAP_SERVERS: $BOOTSTRAP_SERVERS diff --git a/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh b/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh index 6dc9e6adec..9bd75f316c 100755 --- a/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh +++ b/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh @@ -19,7 +19,7 @@ fi # when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription maybe_set_azure_subscription -AZURE_NAME=pg${USER}f${GITHUB_RUN_NUMBER}${TAG} +AZURE_NAME=pg${USER}fm${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} AZURE_RESOURCE_GROUP=$AZURE_NAME AZURE_STORAGE_NAME=$AZURE_NAME @@ -68,7 +68,7 @@ log "Creating local functions project with HTTP trigger" docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "func init LocalFunctionProj --javascript && cd LocalFunctionProj && func new --name HttpExample --template \"HTTP trigger\" --authlevel \"anonymous\"" log "Creating functions app $AZURE_FUNCTIONS_NAME" -az functionapp create --consumption-plan-location $AZURE_REGION --name $AZURE_FUNCTIONS_NAME --resource-group $AZURE_RESOURCE_GROUP --runtime node --storage-account $AZURE_STORAGE_NAME --runtime-version 20 --functions-version 4 --tags owner_email=$AZ_USER --disable-app-insights true +az functionapp create --consumption-plan-location $AZURE_REGION --name $AZURE_FUNCTIONS_NAME --resource-group $AZURE_RESOURCE_GROUP --runtime node --storage-account $AZURE_STORAGE_NAME --runtime-version 18 --functions-version 4 --tags owner_email=$AZ_USER --disable-app-insights true log "Publishing functions app, it will take a while" max_attempts="10" diff --git a/ccloud/fm-azure-functions-sink/stop.sh b/ccloud/fm-azure-functions-sink/stop.sh index e81e6526b9..3c9eaf716f 100755 --- a/ccloud/fm-azure-functions-sink/stop.sh +++ b/ccloud/fm-azure-functions-sink/stop.sh @@ -8,7 +8,7 @@ source ${DIR}/../../scripts/utils.sh maybe_delete_ccloud_environment -AZURE_NAME=pg${USER}f${GITHUB_RUN_NUMBER}${TAG} +AZURE_NAME=pg${USER}fm${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} AZURE_RESOURCE_GROUP=$AZURE_NAME diff --git a/ccloud/fm-databricks-delta-lake-sink/fully-managed-databricks-delta-lake-sink.sh b/ccloud/fm-databricks-delta-lake-sink/fully-managed-databricks-delta-lake-sink.sh index 2e095dbe61..bcd4f49ac5 100755 --- a/ccloud/fm-databricks-delta-lake-sink/fully-managed-databricks-delta-lake-sink.sh +++ b/ccloud/fm-databricks-delta-lake-sink/fully-managed-databricks-delta-lake-sink.sh @@ -87,17 +87,17 @@ playground connector create-or-update --connector $connector_name << EOF EOF wait_for_ccloud_connector_up $connector_name 180 -connector_name="DatabricksDeltaLakeSink_$USER" +connector_name2="DatabricksDeltaLakeSink_$USER" set +e -playground connector delete --connector $connector_name > /dev/null 2>&1 +playground connector delete --connector $connector_name2 > /dev/null 2>&1 set -e log "Creating fully managed connector" -playground connector create-or-update --connector $connector_name << EOF +playground connector create-or-update --connector $connector_name2 << EOF { "topics": "pageviews", "input.data.format": "AVRO", - "name": "$connector_name", + "name": "$connector_name2", "connector.class": "DatabricksDeltaLakeSink", "kafka.auth.mode": "KAFKA_API_KEY", "kafka.api.key": "$CLOUD_KEY", @@ -114,7 +114,7 @@ playground connector create-or-update --connector $connector_name << EOF "tasks.max": "1" } EOF -wait_for_ccloud_connector_up $connector_name 180 +wait_for_ccloud_connector_up $connector_name2 180 sleep 90 @@ -144,3 +144,8 @@ log "Do you want to delete the fully managed connector $connector_name ?" check_if_continue playground connector delete --connector $connector_name + +log "Do you want to delete the fully managed connector $connector_name2 ?" +check_if_continue + +playground connector delete --connector $connector_name2 diff --git a/ccloud/fm-datagen-source/README.md b/ccloud/fm-datagen-source/README.md new file mode 100644 index 0000000000..7de17b1842 --- /dev/null +++ b/ccloud/fm-datagen-source/README.md @@ -0,0 +1,11 @@ +# Fully Managed Datagen Source connector + + +## Objective + +Quickly test [Datagen Source](https://docs.confluent.io/cloud/current/connectors/cc-datagen-source.html) connector. + +## Prerequisites + +See [here](https://kafka-docker-playground.io/#/how-to-use?id=%f0%9f%8c%a4%ef%b8%8f-confluent-cloud-examples) + diff --git a/ccloud/fm-datagen-source/fully-managed-datagen-source.sh b/ccloud/fm-datagen-source/fully-managed-datagen-source.sh new file mode 100755 index 0000000000..028cae3e97 --- /dev/null +++ b/ccloud/fm-datagen-source/fully-managed-datagen-source.sh @@ -0,0 +1,38 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +bootstrap_ccloud_environment + + +connector_name="DatagenSource_$USER" +set +e +playground connector delete --connector $connector_name > /dev/null 2>&1 +set -e + +log "Creating fully managed connector" +playground connector create-or-update --connector $connector_name << EOF +{ + "connector.class": "DatagenSource", + "name": "DatagenSource", + "kafka.auth.mode": "KAFKA_API_KEY", + "kafka.api.key": "$CLOUD_KEY", + "kafka.api.secret": "$CLOUD_SECRET", + "kafka.topic" : "pageviews", + "output.data.format" : "AVRO", + "quickstart" : "PAGEVIEWS", + "max.interval": "10000", + "tasks.max" : "1" +} +EOF +wait_for_ccloud_connector_up $connector_name 180 + +log "Verifying topic pageviews" +playground topic consume --topic pageviews --min-expected-messages 5 --timeout 60 + +log "Do you want to delete the fully managed connector $connector_name ?" +check_if_continue + +playground connector delete --connector $connector_name \ No newline at end of file diff --git a/ccloud/fm-datagen-source/stop.sh b/ccloud/fm-datagen-source/stop.sh new file mode 100755 index 0000000000..227b07f614 --- /dev/null +++ b/ccloud/fm-datagen-source/stop.sh @@ -0,0 +1,8 @@ +#!/bin/bash + + + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +maybe_delete_ccloud_environment \ No newline at end of file diff --git a/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh b/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh index f400222b37..c7f1715a2c 100755 --- a/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh +++ b/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh @@ -99,7 +99,7 @@ do done log "Create table" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -153,7 +153,7 @@ playground connector create-or-update --connector $connector_name << EOF EOF wait_for_ccloud_connector_up $connector_name 180 -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source.sh b/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source.sh index 8c096205da..acaeaa8503 100755 --- a/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source.sh +++ b/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source.sh @@ -74,7 +74,7 @@ do done log "Create table" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -127,7 +127,7 @@ EOF wait_for_ccloud_connector_up $connector_name 180 -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh b/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh index 5bfa829d31..3a1768f61a 100755 --- a/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh +++ b/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh @@ -97,7 +97,7 @@ do done log "Create table" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -152,7 +152,7 @@ playground connector create-or-update --connector $connector_name << EOF EOF wait_for_ccloud_connector_up $connector_name 180 -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source.sh b/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source.sh index fa5f170b96..17672e394f 100755 --- a/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source.sh +++ b/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source.sh @@ -74,7 +74,7 @@ do done log "Create table" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -127,7 +127,7 @@ EOF wait_for_ccloud_connector_up $connector_name 180 -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/ccloud/fm-jdbc-sqlserver-sink/fully-managed-sqlserver-microsoft-sink.sh b/ccloud/fm-jdbc-sqlserver-sink/fully-managed-sqlserver-microsoft-sink.sh index e80e46cedb..aedfe01301 100755 --- a/ccloud/fm-jdbc-sqlserver-sink/fully-managed-sqlserver-microsoft-sink.sh +++ b/ccloud/fm-jdbc-sqlserver-sink/fully-managed-sqlserver-microsoft-sink.sh @@ -131,7 +131,7 @@ EOF sleep 5 log "Show content of sqlserver_table table:" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF select * from sqlserver_table GO EOF diff --git a/ccloud/fm-jdbc-sqlserver-source/fully-managed-sqlserver-source.sh b/ccloud/fm-jdbc-sqlserver-source/fully-managed-sqlserver-source.sh index 356faecbb8..5abf4af173 100755 --- a/ccloud/fm-jdbc-sqlserver-source/fully-managed-sqlserver-source.sh +++ b/ccloud/fm-jdbc-sqlserver-source/fully-managed-sqlserver-source.sh @@ -25,7 +25,7 @@ docker compose up -d --quiet-pull sleep 5 log "Create table" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -105,7 +105,7 @@ playground connector create-or-update --connector $connector_name << EOF EOF wait_for_ccloud_connector_up $connector_name 180 -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/cloudformation/kafka-docker-playground.yml b/cloudformation/kafka-docker-playground.yml index af19047673..6d745feab9 100644 --- a/cloudformation/kafka-docker-playground.yml +++ b/cloudformation/kafka-docker-playground.yml @@ -149,6 +149,8 @@ Resources: git clone https://github.com/vdesabou/kafka-docker-playground.git + rm -rf ~/kafka-docker-playground/reproduction-models/.git + mkdir -p ~/.config/ wget -q https://github.com/vdesabou/kafka-docker-playground/raw/master/cloudformation/dotfiles/starship.toml -o ~/.config/starship.toml diff --git a/connect/connect-azure-functions-sink/azure-functions-sink.sh b/connect/connect-azure-functions-sink/azure-functions-sink.sh index 967ba7fbd2..027a7e88a9 100755 --- a/connect/connect-azure-functions-sink/azure-functions-sink.sh +++ b/connect/connect-azure-functions-sink/azure-functions-sink.sh @@ -68,7 +68,7 @@ log "Creating local functions project with HTTP trigger" docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "func init LocalFunctionProj --javascript && cd LocalFunctionProj && func new --name HttpExample --template \"HTTP trigger\" --authlevel \"anonymous\"" log "Creating functions app $AZURE_FUNCTIONS_NAME" -az functionapp create --consumption-plan-location $AZURE_REGION --name $AZURE_FUNCTIONS_NAME --resource-group $AZURE_RESOURCE_GROUP --runtime node --storage-account $AZURE_STORAGE_NAME --runtime-version 20 --functions-version 4 --tags owner_email=$AZ_USER --disable-app-insights true +az functionapp create --consumption-plan-location $AZURE_REGION --name $AZURE_FUNCTIONS_NAME --resource-group $AZURE_RESOURCE_GROUP --runtime node --storage-account $AZURE_STORAGE_NAME --runtime-version 18 --functions-version 4 --tags owner_email=$AZ_USER --disable-app-insights true log "Publishing functions app, it will take a while" max_attempts="10" diff --git a/connect/connect-azure-service-bus-source/azure-service-bus-source.sh b/connect/connect-azure-service-bus-source/azure-service-bus-source.sh index 5ac6a54943..0854b8d73d 100755 --- a/connect/connect-azure-service-bus-source/azure-service-bus-source.sh +++ b/connect/connect-azure-service-bus-source/azure-service-bus-source.sh @@ -4,6 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh +cd ../../connect/connect-azure-service-bus-source # https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-quickstart-cli#send-and-receive-messages for component in QueuesGettingStarted do @@ -18,6 +19,7 @@ do fi set -e done +cd - if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] then diff --git a/connect/connect-debezium-sqlserver-source/README.md b/connect/connect-debezium-sqlserver-source/README.md index 868ea4d01c..182484121c 100644 --- a/connect/connect-debezium-sqlserver-source/README.md +++ b/connect/connect-debezium-sqlserver-source/README.md @@ -24,7 +24,7 @@ $ just use command and search for debezium-sqlserver-source.sh Load inventory.sql to SQL Server ```bash -$ cat ../../connect/connect-debezium-sqlserver-source/inventory.sql | docker exec -i sqlserver bash -c '/opt/mssql-tools/bin/sqlcmd -U sa -P Password!' +$ cat ../../connect/connect-debezium-sqlserver-source/inventory.sql | docker exec -i sqlserver bash -c '/opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password!' ``` @@ -58,7 +58,7 @@ $ curl -X PUT \ Insert one more row: ```bash -$ docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +$ docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-incremental-snapshot.sh b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-incremental-snapshot.sh index f99ea0a7af..14c650771b 100755 --- a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-incremental-snapshot.sh +++ b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-incremental-snapshot.sh @@ -15,7 +15,7 @@ playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker- log "Create table" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -43,7 +43,7 @@ EOF # https://debezium.io/documentation/reference/1.9/configuration/signalling.html#sending-signals-to-a-debezium-connector log "Creating a signaling data collection" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; CREATE TABLE debezium_signal (id VARCHAR(42) PRIMARY KEY, type VARCHAR(32) NOT NULL, data VARCHAR(2048) NULL); EXEC sys.sp_cdc_enable_table @source_schema = 'dbo', @source_name = 'debezium_signal', @role_name = NULL, @supports_net_changes = 0; @@ -79,7 +79,7 @@ EOF sleep 5 log "Insert another row" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO @@ -90,7 +90,7 @@ playground topic consume --topic server1.testDB.dbo.customers --min-expected-mes log "Add another table customers2" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; CREATE TABLE customers2 ( id INTEGER IDENTITY(1001,1) NOT NULL PRIMARY KEY, @@ -142,7 +142,7 @@ playground connector create-or-update --connector debezium-sqlserver-source << EOF log "Add another table customers2" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers2(first_name,last_name,email) VALUES ('Anne2','Kretchmar2','annek2@noanswer.org'); @@ -155,7 +155,7 @@ log "Verifying topic server1.testDB.dbo.customers2 : there will be only the new playground topic consume --topic server1.testDB.dbo.customers2 --min-expected-messages 1 --timeout 60 log "Trigger Ad hoc snapshot" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO debezium_signal (id, type, data) VALUES('captain adhoc $RANDOM', 'execute-snapshot', '{"data-collections": ["testDB.dbo.customers2"], "type":"incremental"}'); GO diff --git a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh index 59246e0929..a512e970a4 100755 --- a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh +++ b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh @@ -64,7 +64,7 @@ playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker- log "Create table" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -123,7 +123,7 @@ EOF sleep 5 -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-standalone-worker.sh b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-standalone-worker.sh index 8042786dfe..715de126b5 100755 --- a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-standalone-worker.sh +++ b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-standalone-worker.sh @@ -17,7 +17,7 @@ fi playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.standalone-worker.yml" --wait-for-control-center log "Create table" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -49,7 +49,7 @@ docker exec -d connect bash -c 'connect-standalone /tmp/worker.properties /tmp/c log "Sleeping 60 seconds to let the standalone connector doing the work" sleep 60 -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source.sh b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source.sh index d974e61c9b..27ee4e8289 100755 --- a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source.sh +++ b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source.sh @@ -37,7 +37,7 @@ playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker- log "Create table" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -92,7 +92,7 @@ EOF sleep 5 -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-gcp-google-pubsub-sink/docker-compose.plaintext.yml b/connect/connect-gcp-google-pubsub-sink/docker-compose.plaintext.yml index ca85fa1bc5..23f1f8f78c 100644 --- a/connect/connect-gcp-google-pubsub-sink/docker-compose.plaintext.yml +++ b/connect/connect-gcp-google-pubsub-sink/docker-compose.plaintext.yml @@ -6,5 +6,6 @@ services: - ../../connect/connect-gcp-google-pubsub-sink/pubsub-group-kafka-connector-1.2.0.jar:/usr/share/confluent-hub-components/pubsub-group-kafka-connector/pubsub-group-kafka-connector-1.2.0.jar - ../../connect/connect-gcp-google-pubsub-sink/grpc-netty-1.54.0.jar:/usr/share/confluent-hub-components/pubsub-group-kafka-connector/grpc-netty-1.54.0.jar + - ../../connect/connect-gcp-google-pubsub-sink/grpc-rls-1.55.3.jar:/usr/share/confluent-hub-components/pubsub-group-kafka-connector/grpc-rls-1.55.3.jar environment: CONNECT_PLUGIN_PATH: /usr/share/java/,/usr/share/confluent-hub-components/ \ No newline at end of file diff --git a/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh b/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh index 06c5ce25a4..43eaef97c5 100755 --- a/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh +++ b/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh @@ -22,6 +22,11 @@ then wget -q https://repo1.maven.org/maven2/io/grpc/grpc-netty/1.54.0/grpc-netty-1.54.0.jar fi +if [ ! -f ${DIR}/grpc-rls-1.55.3.jar ] +then + wget -q https://repo1.maven.org/maven2/io/grpc/grpc-rls/1.55.3/grpc-rls-1.55.3.jar +fi + GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then diff --git a/connect/connect-gcp-google-pubsub-source/docker-compose.plaintext.yml b/connect/connect-gcp-google-pubsub-source/docker-compose.plaintext.yml index 05c1732285..bd3354ea82 100644 --- a/connect/connect-gcp-google-pubsub-source/docker-compose.plaintext.yml +++ b/connect/connect-gcp-google-pubsub-source/docker-compose.plaintext.yml @@ -6,5 +6,6 @@ services: - ../../connect/connect-gcp-google-pubsub-source/pubsub-group-kafka-connector-1.2.0.jar:/usr/share/confluent-hub-components/pubsub-group-kafka-connector/pubsub-group-kafka-connector-1.2.0.jar - ../../connect/connect-gcp-google-pubsub-source/grpc-netty-1.54.0.jar:/usr/share/confluent-hub-components/pubsub-group-kafka-connector/grpc-netty-1.54.0.jar + - ../../connect/connect-gcp-google-pubsub-source/grpc-rls-1.55.3.jar:/usr/share/confluent-hub-components/pubsub-group-kafka-connector/grpc-rls-1.55.3.jar environment: CONNECT_PLUGIN_PATH: /usr/share/java/,/usr/share/confluent-hub-components/ \ No newline at end of file diff --git a/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh b/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh index 7eafbc8fcc..07e04923d0 100755 --- a/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh +++ b/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh @@ -22,6 +22,11 @@ then wget -q https://repo1.maven.org/maven2/io/grpc/grpc-netty/1.54.0/grpc-netty-1.54.0.jar fi +if [ ! -f ${DIR}/grpc-rls-1.55.3.jar ] +then + wget -q https://repo1.maven.org/maven2/io/grpc/grpc-rls/1.55.3/grpc-rls-1.55.3.jar +fi + GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then diff --git a/connect/connect-hbase-sink/docker-compose.plaintext.kerberos.yml b/connect/connect-hbase-sink/docker-compose.plaintext.kerberos.yml index 7368bf3cac..af2e8aceb4 100644 --- a/connect/connect-hbase-sink/docker-compose.plaintext.kerberos.yml +++ b/connect/connect-hbase-sink/docker-compose.plaintext.kerberos.yml @@ -40,6 +40,8 @@ services: hostname: connect.kerberos-demo.local environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-hbase + # JDK 17 + KAFKA_OPTS: --add-opens=java.security.jgss/sun.security.krb5=ALL-UNNAMED volumes: - ../../connect/connect-hbase-sink/kerberos/krb5.conf:/etc/krb5.conf - krb-server:/opt/keytabs/ diff --git a/connect/connect-hdfs2-sink/docker-compose.plaintext.yml b/connect/connect-hdfs2-sink/docker-compose.plaintext.yml index 159c11feab..173377c35e 100644 --- a/connect/connect-hdfs2-sink/docker-compose.plaintext.yml +++ b/connect/connect-hdfs2-sink/docker-compose.plaintext.yml @@ -70,6 +70,8 @@ services: - hive-metastore environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-hdfs + # JDK 17 + KAFKA_OPTS: --add-opens java.base/java.net=ALL-UNNAMED volumes: namenode: diff --git a/connect/connect-hdfs2-source/docker-compose.plaintext.yml b/connect/connect-hdfs2-source/docker-compose.plaintext.yml index 172492a437..30b8fa6a24 100644 --- a/connect/connect-hdfs2-source/docker-compose.plaintext.yml +++ b/connect/connect-hdfs2-source/docker-compose.plaintext.yml @@ -73,6 +73,8 @@ - hive-metastore environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-hdfs2-source,/usr/share/confluent-hub-components/confluentinc-kafka-connect-hdfs + # JDK 17 + KAFKA_OPTS: --add-opens java.base/java.net=ALL-UNNAMED volumes: namenode: diff --git a/connect/connect-hdfs3-sink/docker-compose.plaintext.yml b/connect/connect-hdfs3-sink/docker-compose.plaintext.yml index bd0ebc4270..6b70597860 100644 --- a/connect/connect-hdfs3-sink/docker-compose.plaintext.yml +++ b/connect/connect-hdfs3-sink/docker-compose.plaintext.yml @@ -99,6 +99,8 @@ services: - hive-metastore environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-hdfs3 + # JDK 17 + KAFKA_OPTS: --add-opens java.base/java.net=ALL-UNNAMED volumes: datanode: diff --git a/connect/connect-hdfs3-source/docker-compose.plaintext.yml b/connect/connect-hdfs3-source/docker-compose.plaintext.yml index 5f9e2b9073..6299259608 100644 --- a/connect/connect-hdfs3-source/docker-compose.plaintext.yml +++ b/connect/connect-hdfs3-source/docker-compose.plaintext.yml @@ -99,6 +99,8 @@ - hive-metastore environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-hdfs3-source,/usr/share/confluent-hub-components/confluentinc-kafka-connect-hdfs3 + # JDK 17 + KAFKA_OPTS: --add-opens java.base/java.net=ALL-UNNAMED volumes: datanode: diff --git a/connect/connect-http-sink/http_no_auth.sh b/connect/connect-http-sink/http_no_auth.sh index a25caea620..e54a271c2b 100755 --- a/connect/connect-http-sink/http_no_auth.sh +++ b/connect/connect-http-sink/http_no_auth.sh @@ -41,8 +41,9 @@ playground debug log-level set --package "org.apache.http" --level TRACE log "Set webserver to reply with 200" curl -X PUT -H "Content-Type: application/json" --data '{"errorCode": 200}' http://localhost:9006/set-response-error-code +curl -X PUT -H "Content-Type: application/json" --data '{"message":"Hello, World!"}' http://localhost:9006/set-response-body + # curl -X PUT -H "Content-Type: application/json" --data '{"delay": 2000}' http://localhost:9006/set-response-time -# curl -X PUT -H "Content-Type: application/json" --data '{"message":"Hello, World!"}' http://localhost:9006/set-response-body log "Creating http-sink connector" playground connector create-or-update --connector http-sink << EOF diff --git a/connect/connect-http-sink/httpserver/server.js b/connect/connect-http-sink/httpserver/server.js index 778621727e..78836859fb 100644 --- a/connect/connect-http-sink/httpserver/server.js +++ b/connect/connect-http-sink/httpserver/server.js @@ -21,7 +21,10 @@ app.use((req, res, next) => { }); app.get('/', (req, res) => { - res.status(errorCode).json(responseBody); + res.status(errorCode) + .set('Content-Type', 'application/json') + .set('Custom-Header', 'Hello') + .json(responseBody); console.log("headers:"); console.log(req.headers); console.log("body:"); @@ -30,7 +33,10 @@ app.get('/', (req, res) => { }); app.post('/', (req, res) => { - res.status(errorCode).json(responseBody); + res.status(errorCode) + .set('Content-Type', 'application/json') + .set('Custom-Header', 'Hello') + .json(responseBody); console.log("headers:"); console.log(req.headers); console.log("body:"); @@ -39,7 +45,10 @@ app.post('/', (req, res) => { }); app.put('/', (req, res) => { - res.status(errorCode).json(responseBody); + res.status(errorCode) + .set('Content-Type', 'application/json') + .set('Custom-Header', 'Hello') + .json(responseBody); console.log("headers:"); console.log(req.headers); console.log("body:"); @@ -48,7 +57,10 @@ app.put('/', (req, res) => { }); app.delete('/', (req, res) => { - res.status(errorCode).json(responseBody); + res.status(errorCode) + .set('Content-Type', 'application/json') + .set('Custom-Header', 'Hello') + .json(responseBody); console.log("headers:"); console.log(req.headers); console.log("body:"); diff --git a/connect/connect-iceberg-sink/spark/Dockerfile b/connect/connect-iceberg-sink/spark/Dockerfile index 6fbea26a9f..801cdcb975 100644 --- a/connect/connect-iceberg-sink/spark/Dockerfile +++ b/connect/connect-iceberg-sink/spark/Dockerfile @@ -48,7 +48,7 @@ ENV PYTHONPATH=$SPARK_HOME/python:$SPARK_HOME/python/lib/py4j-0.10.9.7-src.zip:$ WORKDIR ${SPARK_HOME} -ENV SPARK_VERSION=3.5.1 +ENV SPARK_VERSION=3.5.2 ENV SPARK_MAJOR_VERSION=3.5 ENV ICEBERG_VERSION=1.5.0 diff --git a/connect/connect-jdbc-sqlserver-sink/README.md b/connect/connect-jdbc-sqlserver-sink/README.md index 799963eb08..bfeeb9d5f0 100644 --- a/connect/connect-jdbc-sqlserver-sink/README.md +++ b/connect/connect-jdbc-sqlserver-sink/README.md @@ -163,7 +163,7 @@ EOF Show content of `orders` table: ```bash -$ ocker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +$ ocker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF select * from orders GO EOF diff --git a/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh b/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh index 9c366f8185..4037723924 100755 --- a/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh +++ b/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh @@ -131,7 +131,7 @@ EOF sleep 5 log "Show content of orders table:" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF select * from orders GO EOF diff --git a/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink.sh b/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink.sh index a41e16b08c..696849db5b 100755 --- a/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink.sh +++ b/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink.sh @@ -74,7 +74,7 @@ EOF sleep 5 log "Show content of orders table:" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF select * from orders GO EOF diff --git a/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh b/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh index 06aee1b0ee..f5146424dc 100755 --- a/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh +++ b/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh @@ -134,7 +134,7 @@ EOF sleep 5 log "Show content of orders table:" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF select * from orders GO EOF diff --git a/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink.sh b/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink.sh index e96b18159f..a1a6e3d889 100755 --- a/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink.sh +++ b/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink.sh @@ -86,7 +86,7 @@ EOF sleep 5 log "Show content of orders table:" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF select * from orders GO EOF diff --git a/connect/connect-jdbc-sqlserver-source/README.md b/connect/connect-jdbc-sqlserver-source/README.md index e6c75ac321..dc2823b4f3 100644 --- a/connect/connect-jdbc-sqlserver-source/README.md +++ b/connect/connect-jdbc-sqlserver-source/README.md @@ -32,7 +32,7 @@ $ just use command and search for sqlserver-microsoft-ssl.sh in Load inventory.sql to SQL Server ```bash -$ cat ../../connect/connect-jdbc-sqlserver-source/inventory.sql | docker exec -i sqlserver bash -c '/opt/mssql-tools/bin/sqlcmd -U sa -P Password!' +$ cat ../../connect/connect-jdbc-sqlserver-source/inventory.sql | docker exec -i sqlserver bash -c '/opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password!' ``` ### JTDS JDBC driver @@ -171,7 +171,7 @@ $ curl -X PUT \ Insert one more row: ```bash -$ docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +$ docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh b/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh index 35404177e1..cb777c7ca4 100755 --- a/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh +++ b/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh @@ -65,7 +65,7 @@ PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.jtds-ssl.yml" log "Create table" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -110,7 +110,7 @@ EOF sleep 5 -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-jdbc-sqlserver-source/sqlserver-jtds.sh b/connect/connect-jdbc-sqlserver-source/sqlserver-jtds.sh index 5e06281730..6865cb6d5a 100755 --- a/connect/connect-jdbc-sqlserver-source/sqlserver-jtds.sh +++ b/connect/connect-jdbc-sqlserver-source/sqlserver-jtds.sh @@ -30,7 +30,7 @@ PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.jtds.yml" log "Create table" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -75,7 +75,7 @@ EOF sleep 5 -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh b/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh index 0e0574429d..0ade2f6206 100755 --- a/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh +++ b/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh @@ -67,7 +67,7 @@ PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.microsoft-ssl.yml" log "Create table" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -113,7 +113,7 @@ EOF sleep 5 -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft.sh b/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft.sh index 367fd79dbb..2392ccbabf 100755 --- a/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft.sh +++ b/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft.sh @@ -40,7 +40,7 @@ PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.microsoft.yml" log "Create table" -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -85,7 +85,7 @@ EOF sleep 5 -docker exec -i sqlserver /opt/mssql-tools/bin/sqlcmd -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-jms-weblogic-sink/docker-compose.plaintext.yml b/connect/connect-jms-weblogic-sink/docker-compose.plaintext.yml index 857c9a9bff..55fe0b249b 100644 --- a/connect/connect-jms-weblogic-sink/docker-compose.plaintext.yml +++ b/connect/connect-jms-weblogic-sink/docker-compose.plaintext.yml @@ -25,4 +25,6 @@ services: - ../../connect/connect-jms-weblogic-sink/jms-receiver/lib/wlthint3client.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jms-sink/lib/wlthint3client.jar environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jms-sink + # JDK 17 + KAFKA_OPTS: --add-opens java.base/java.io=ALL-UNNAMED # CONNECT_LOG4J_ROOT_LOGLEVEL: TRACE diff --git a/connect/connect-jms-weblogic-source/docker-compose.plaintext.yml b/connect/connect-jms-weblogic-source/docker-compose.plaintext.yml index ed8e22a179..254162eca6 100644 --- a/connect/connect-jms-weblogic-source/docker-compose.plaintext.yml +++ b/connect/connect-jms-weblogic-source/docker-compose.plaintext.yml @@ -25,4 +25,6 @@ services: - ../../connect/connect-jms-weblogic-source/jms-sender/lib/wlthint3client.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jms/lib/wlthint3client.jar environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jms + # JDK 17 + KAFKA_OPTS: --add-opens java.base/java.io=ALL-UNNAMED # CONNECT_LOG4J_ROOT_LOGLEVEL: TRACE diff --git a/connect/connect-mapr-sink/mapr-sink.sh b/connect/connect-mapr-sink/mapr-sink.sh index 75bb435dbe..51448d1cb7 100755 --- a/connect/connect-mapr-sink/mapr-sink.sh +++ b/connect/connect-mapr-sink/mapr-sink.sh @@ -40,8 +40,8 @@ log "Installing Mapr Client" # RHEL # required deps for mapr-client docker exec -i --privileged --user root connect bash -c "chmod a+rw /etc/yum.repos.d/maprtech.repo" -docker exec -i --privileged --user root connect bash -c "rpm -i http://mirror.centos.org/centos/7/os/x86_64/Packages/mtools-4.0.18-5.el7.x86_64.rpm" -docker exec -i --privileged --user root connect bash -c "rpm -i http://mirror.centos.org/centos/7/os/x86_64/Packages/syslinux-4.05-15.el7.x86_64.rpm" +docker exec -i --privileged --user root connect bash -c "rpm -i https://buildlogs.centos.org/c7.00.02/mtools/20140529191653/4.0.18-5.el7.x86_64/mtools-4.0.18-5.el7.x86_64.rpm" +docker exec -i --privileged --user root connect bash -c "rpm -i https://downloads.storagecraft.com/_xafe/public/OneSystem/repo/el7/os/syslinux-4.05-15.el7.x86_64.rpm" docker exec -i --privileged --user root connect bash -c "yum -y install --disablerepo='Confluent*' --disablerepo='mapr*' jre-1.8.0-openjdk hostname findutils net-tools" diff --git a/connect/connect-weblogic-source/docker-compose.plaintext.yml b/connect/connect-weblogic-source/docker-compose.plaintext.yml index 3fa7cf26d1..d95557542d 100644 --- a/connect/connect-weblogic-source/docker-compose.plaintext.yml +++ b/connect/connect-weblogic-source/docker-compose.plaintext.yml @@ -24,4 +24,6 @@ services: - ../../connect/connect-weblogic-source/jms-sender/lib/wlthint3client.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-weblogic/lib/wlthint3client.jar environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-weblogic + # JDK 17 + KAFKA_OPTS: --add-opens java.base/java.io=ALL-UNNAMED # CONNECT_LOG4J_ROOT_LOGLEVEL: TRACE diff --git a/docs/content-template.md b/docs/content-template.md index 328b17dc9b..cda93b1c6a 100644 --- a/docs/content-template.md +++ b/docs/content-template.md @@ -205,6 +205,7 @@ - [Azure Service Bus Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-azure-service-bus-source) :ccloud/fm-azure-service-bus-source: - [Azure Synapse Analytics Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-azure-synapse-analytics-sink) :ccloud/fm-azure-synapse-analytics-sink: - [Databricks Delta Lake table Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-databricks-delta-lake-sink) :ccloud/fm-databricks-delta-lake-sink: + - [Datagen Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-datagen-source) :ccloud/fm-datagen-source: - [Datadog Metrics Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-datadog-metrics-sink) :ccloud/fm-datadog-metrics-sink: - [Debezium CDC Microsoft SQL Server Legacy Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-debezium-sqlserver-legacy-source) (also with 🔑 SSL) :ccloud/fm-debezium-sqlserver-legacy-source: - [Debezium CDC Microsoft SQL Server V2 Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-debezium-sqlserver-v2-source) (also with 🔑 SSL) :ccloud/fm-debezium-sqlserver-v2-source: diff --git a/environment/rbac-sasl-plain/docker-compose.yml b/environment/rbac-sasl-plain/docker-compose.yml index da62097887..ac3462b428 100644 --- a/environment/rbac-sasl-plain/docker-compose.yml +++ b/environment/rbac-sasl-plain/docker-compose.yml @@ -343,7 +343,7 @@ services: cp /usr/share/java/kafka-connect-replicator/replicator-rest-extension-*.jar /etc/kafka-connect/jars/ && \ /etc/confluent/docker/run'" environment: - CUB_CLASSPATH: '/usr/share/java/kafka/*:/etc/confluent/docker/docker-utils.jar:/usr/share/java/cp-base-new/*:/usr/share/java/confluent-security/connect/*' + CUB_CLASSPATH: '/usr/share/java/kafka/*:/etc/confluent/docker/docker-utils.jar:/usr/share/java/cp-base-new/*:/usr/share/java/confluent-security/connect/*:/usr/share/java/confluent-secret-registry/*' CONNECT_BOOTSTRAP_SERVERS: broker:10091 CONNECT_SECURITY_PROTOCOL: SASL_PLAINTEXT @@ -429,7 +429,7 @@ services: cp /usr/share/java/kafka-connect-replicator/replicator-rest-extension-*.jar /etc/kafka-connect/jars/ && \ /etc/confluent/docker/run'" environment: - CUB_CLASSPATH: '/usr/share/java/kafka/*:/etc/confluent/docker/docker-utils.jar:/usr/share/java/cp-base-new/*:/usr/share/java/confluent-security/connect/*' + CUB_CLASSPATH: '/usr/share/java/kafka/*:/etc/confluent/docker/docker-utils.jar:/usr/share/java/cp-base-new/*:/usr/share/java/confluent-security/connect/*:/usr/share/java/confluent-secret-registry/*' CONNECT_BOOTSTRAP_SERVERS: broker:10091 CONNECT_SECURITY_PROTOCOL: SASL_PLAINTEXT @@ -515,7 +515,7 @@ services: cp /usr/share/java/kafka-connect-replicator/replicator-rest-extension-*.jar /etc/kafka-connect/jars/ && \ /etc/confluent/docker/run'" environment: - CUB_CLASSPATH: '/usr/share/java/kafka/*:/etc/confluent/docker/docker-utils.jar:/usr/share/java/cp-base-new/*:/usr/share/java/confluent-security/connect/*' + CUB_CLASSPATH: '/usr/share/java/kafka/*:/etc/confluent/docker/docker-utils.jar:/usr/share/java/cp-base-new/*:/usr/share/java/confluent-security/connect/*:/usr/share/java/confluent-secret-registry/*' CONNECT_BOOTSTRAP_SERVERS: broker:10091 CONNECT_SECURITY_PROTOCOL: SASL_PLAINTEXT diff --git a/environment/rbac-sasl-plain/scripts/helper/create-role-bindings.sh b/environment/rbac-sasl-plain/scripts/helper/create-role-bindings.sh index 1e3031201b..f35b0fa186 100755 --- a/environment/rbac-sasl-plain/scripts/helper/create-role-bindings.sh +++ b/environment/rbac-sasl-plain/scripts/helper/create-role-bindings.sh @@ -123,6 +123,20 @@ do --kafka-cluster-id $KAFKA_CLUSTER_ID done +# in case EOS is used https://cwiki.apache.org/confluence/display/KAFKA/KIP-618%3A+Exactly-Once+Support+for+Source+Connectors +confluent iam rolebinding create \ + --principal $CONNECT_ADMIN \ + --role ResourceOwner \ + --resource TransactionalId:connect-cluster-connect-cluster \ + --kafka-cluster-id $KAFKA_CLUSTER_ID + +# enable.idempotence=true requires IdempotentWrite +confluent iam rolebinding create \ + --principal $CONNECT_ADMIN \ + --role DeveloperWrite \ + --resource Cluster:kafka-cluster \ + --kafka-cluster-id $KAFKA_CLUSTER_ID + ################################### Connectors ################################### echo "Creating role bindings for any connector" @@ -159,6 +173,13 @@ confluent iam rolebinding create \ --kafka-cluster-id $KAFKA_CLUSTER_ID \ --schema-registry-cluster-id $SR +# in case EOS is used https://cwiki.apache.org/confluence/display/KAFKA/KIP-618%3A+Exactly-Once+Support+for+Source+Connectors +confluent iam rolebinding create \ + --principal $CONNECTOR_PRINCIPAL \ + --role ResourceOwner \ + --resource TransactionalId:* \ + --kafka-cluster-id $KAFKA_CLUSTER_ID + ################################### ksqlDB Admin ################################### echo "Creating role bindings for ksqlDB Admin" diff --git a/scripts/cli/completions.bash b/scripts/cli/completions.bash index 4a77c0e1ab..3d26d236c2 100644 --- a/scripts/cli/completions.bash +++ b/scripts/cli/completions.bash @@ -1001,7 +1001,7 @@ _playground_completions() { ;; *'debug heap-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") ;; *'debug log-level'*) diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index fe11654f27..822e3bb3dc 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -126,7 +126,6 @@ gridgain/ignite-connector hazelcast/hazelcast-jet-kafka hazelcast/kafka-connector hivemq/enterprise-extension -hvr/hvr-cdc ibm/data-replication imply/druid-kafka-indexing-service infoviewsystems/kafka-connect-as400 @@ -173,10 +172,12 @@ pivotal/greenplum-integration precisely/connect privitar/privitar-kafka-connector push/diffusion-connector +qdrant/qdrant-kafka qlik/qlik-cdc questdb/kafka-questdb-connector rahulbats/kafka-connect-odpsapsource rapidapi/rapidapi-enterprise-hub +rayokota/kafka-connect-jsonata redhatinsights/expandjsonsmt redis/redis-enterprise-kafka redis/redis-kafka-connect @@ -193,9 +194,12 @@ snowflakeinc/snowflake-kafka-connector splunk/kafka-connect-splunk spoudinc/spoud-agoora sqdata/sqdata-connector +streamsendio/file-chunk-sink +streamsendio/file-chunk-source streamsets/streamsets-sdc swim/swim-kafka-connect symetryml/kafka-connector +synthesis/synthesis-fix-connector tabular/iceberg-kafka-connect thomaskwscott/kafka-connect-shell-sink thomaskwscott/kafka-connect-shell-source diff --git a/scripts/cli/confluent-kafka-region-list.txt b/scripts/cli/confluent-kafka-region-list.txt index 295ab2398e..d9f55330d5 100644 --- a/scripts/cli/confluent-kafka-region-list.txt +++ b/scripts/cli/confluent-kafka-region-list.txt @@ -1,90 +1,98 @@ -aws/af-south-1 -aws/ap-east-1 -aws/ap-northeast-1 -aws/ap-northeast-2 -aws/ap-northeast-3 -aws/ap-south-1 -aws/ap-south-2 -aws/ap-southeast-1 -aws/ap-southeast-2 -aws/ap-southeast-3 -aws/ap-southeast-4 -aws/ca-central-1 -aws/ca-west-1 -aws/eu-central-1 -aws/eu-central-2 -aws/eu-north-1 -aws/eu-south-1 -aws/eu-south-2 -aws/eu-west-1 -aws/eu-west-2 -aws/eu-west-3 -aws/il-central-1 -aws/me-central-1 -aws/me-south-1 -aws/sa-east-1 -aws/us-east-1 -aws/us-east-2 -aws/us-west-2 -azure/australiaeast -azure/brazilsouth -azure/canadacentral -azure/centralindia -azure/centralus -azure/eastasia -azure/eastus -azure/eastus2 -azure/francecentral -azure/germanywestcentral -azure/italynorth -azure/japaneast -azure/koreacentral -azure/mexicocentral -azure/northeurope -azure/norwayeast -azure/qatarcentral -azure/southafricanorth -azure/southcentralus -azure/southeastasia -azure/swedencentral -azure/switzerlandnorth -azure/uaenorth -azure/uksouth -azure/westeurope -azure/westus2 -azure/westus3 -gcp/asia-east1 -gcp/asia-east2 -gcp/asia-northeast1 -gcp/asia-northeast2 -gcp/asia-northeast3 -gcp/asia-south1 -gcp/asia-south2 -gcp/asia-southeast1 -gcp/asia-southeast2 -gcp/australia-southeast1 -gcp/australia-southeast2 -gcp/europe-central2 -gcp/europe-north1 -gcp/europe-southwest1 -gcp/europe-west1 -gcp/europe-west12 -gcp/europe-west2 -gcp/europe-west3 -gcp/europe-west4 -gcp/europe-west6 -gcp/europe-west8 -gcp/europe-west9 -gcp/me-central1 -gcp/me-central2 -gcp/me-west1 -gcp/northamerica-northeast1 -gcp/northamerica-northeast2 -gcp/southamerica-east1 -gcp/southamerica-west1 -gcp/us-central1 -gcp/us-east1 -gcp/us-east4 -gcp/us-west1 -gcp/us-west2 -gcp/us-west4 +Name/Region +Bahrain(me-south-1)/me-south-1 +Belgium(europe-west1)/europe-west1 +Calgary(ca-west-1)/ca-west-1 +Canada(ca-central-1)/ca-central-1 +CapeTown(af-south-1)/af-south-1 +Dallas(us-south1)/us-south1 +Dammam(me-central2)/me-central2 +Delhi(asia-south2)/asia-south2 +Doha(me-central1)/me-central1 +Doha(qatarcentral)/qatarcentral +Dubai(uaenorth)/uaenorth +Finland(europe-north1)/europe-north1 +Frankfurt(eu-central-1)/eu-central-1 +Frankfurt(europe-west3)/europe-west3 +Frankfurt(germanywestcentral)/germanywestcentral +Gävle(swedencentral)/swedencentral +HongKong(ap-east-1)/ap-east-1 +HongKong(asia-east2)/asia-east2 +HongKong(eastasia)/eastasia +Hyderabad(ap-south-2)/ap-south-2 +Iowa(centralus)/centralus +Iowa(us-central1)/us-central1 +Ireland(eu-west-1)/eu-west-1 +Ireland(northeurope)/northeurope +Jakarta(ap-southeast-3)/ap-southeast-3 +Jakarta(asia-southeast2)/asia-southeast2 +Johannesburg/southafricanorth +(southafricanorth)/ +LasVegas(us-west4)/us-west4 +London(eu-west-2)/eu-west-2 +London(europe-west2)/europe-west2 +London(uksouth)/uksouth +LosAngeles(us-west2)/us-west2 +Madrid(europe-southwest1)/europe-southwest1 +Melbourne(ap-southeast-4)/ap-southeast-4 +Melbourne/australia-southeast2 +(australia-southeast2)/ +MexicoCentral(mexicocentral)/mexicocentral +Milan(eu-south-1)/eu-south-1 +Milan(europe-west8)/europe-west8 +Milan(italynorth)/italynorth +Montreal/northamerica-northeast1 +(northamerica-northeast1)/ +Mumbai(ap-south-1)/ap-south-1 +Mumbai(asia-south1)/asia-south1 +N.Virginia(us-east-1)/us-east-1 +N.Virginia(us-east4)/us-east4 +Netherlands(europe-west4)/europe-west4 +Netherlands(westeurope)/westeurope +NewSouthWales/australiaeast +(australiaeast)/ +Ohio(us-east-2)/us-east-2 +Oregon(us-west-2)/us-west-2 +Oregon(us-west1)/us-west1 +Osaka(ap-northeast-3)/ap-northeast-3 +Osaka(asia-northeast2)/asia-northeast2 +Oslo(norwayeast)/norwayeast +Paris(eu-west-3)/eu-west-3 +Paris(europe-west9)/europe-west9 +Paris(francecentral)/francecentral +Phoenix(westus3)/westus3 +Pune(centralindia)/centralindia +S.Carolina(us-east1)/us-east1 +Santiago(southamerica-west1)/southamerica-west1 +SaoPaulo(southamerica-east1)/southamerica-east1 +SaoPaulostate(brazilsouth)/brazilsouth +Seoul(ap-northeast-2)/ap-northeast-2 +Seoul(asia-northeast3)/asia-northeast3 +Seoul(koreacentral)/koreacentral +Singapore(ap-southeast-1)/ap-southeast-1 +Singapore(asia-southeast1)/asia-southeast1 +Singapore(southeastasia)/southeastasia +Spain(eu-south-2)/eu-south-2 +Spain(spaincentral)/spaincentral +Stockholm(eu-north-1)/eu-north-1 +Sydney(ap-southeast-2)/ap-southeast-2 +Sydney(australia-southeast1)/australia-southeast1 +SãoPaulo(sa-east-1)/sa-east-1 +Taiwan(asia-east1)/asia-east1 +TelAviv(il-central-1)/il-central-1 +TelAviv(me-west1)/me-west1 +Texas(southcentralus)/southcentralus +Tokyo(ap-northeast-1)/ap-northeast-1 +Tokyo(asia-northeast1)/asia-northeast1 +Tokyo(japaneast)/japaneast +Toronto(canadacentral)/canadacentral +Toronto/northamerica-northeast2 +(northamerica-northeast2)/ +Turin(europe-west12)/europe-west12 +UAE(me-central-1)/me-central-1 +Virginia(eastus)/eastus +Virginia(eastus2)/eastus2 +Warsaw(europe-central2)/europe-central2 +Washington(westus2)/westus2 +Zurich(eu-central-2)/eu-central-2 +Zurich(europe-west6)/europe-west6 +Zurich(switzerlandnorth)/switzerlandnorth diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index 1b7e073895..102ae3bb9b 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -1068,7 +1068,7 @@ }, { "name": "heap-dump", - "description": "👻 Take a heap dump\n \n 🔖 It will save output to a .hprof file. VisualVM (https://visualvm.github.io/) or MAT (https://www.eclipse.org/mat/) can be used to read the file.\n", + "description": "👻 Take a heap dump\n \n 🔖 It will save output to a .hprof file. VisualVM (https://visualvm.github.io/) or MAT (https://www.eclipse.org/mat/) can be used to read the file.\n \n It will run a full gc first. If you don't want this, use \n", "usage": "playground debug heap-dump [OPTIONS]", "options": [ { @@ -1078,6 +1078,20 @@ ], "argument": "connect", "description": "🐳 Container name\n\nDefault value: connect\n" + }, + { + "names": [ + "--live" + ], + "argument": "", + "description": "🧬 dump only live objects; if not specified, all objects in the heap are dumped\n" + }, + { + "names": [ + "--histo" + ], + "argument": "", + "description": "📊 print histogram of java object heap\n" } ] }, diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index 864bc31dc9..f678fdac76 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -1203,6 +1203,8 @@ subcommands: 👻 Take a heap dump 🔖 It will save output to a .hprof file. VisualVM (https://visualvm.github.io/) or MAT (https://www.eclipse.org/mat/) can be used to read the file. + + It will run a full gc first. If you don't want this, use usage: playground debug heap-dump [OPTIONS] options: - names: @@ -1214,6 +1216,18 @@ subcommands: Default value: connect + - names: + - --live + argument: "" + description: | + 🧬 dump only live objects; if not specified, all objects in the heap are dumped + + - names: + - --histo + argument: "" + description: | + 📊 print histogram of java object heap + - name: tcp-dump description: | 🕵️‍♂️ Take a tcp dump (sniffing network) diff --git a/scripts/cli/tag-list.txt b/scripts/cli/tag-list.txt index fccb17529a..a8a6a36591 100644 --- a/scripts/cli/tag-list.txt +++ b/scripts/cli/tag-list.txt @@ -44,9 +44,9 @@ 5.5.10 5.5.11 5.5.12 -5.5.2 5.5.3 5.5.4 +5.5.5 5.5.6 5.5.7 5.5.8 @@ -66,7 +66,6 @@ 6.0.6 6.0.7 6.0.8 -6.0.9 6.1.0 6.1.1 6.1.10 @@ -78,11 +77,9 @@ 6.1.2 6.1.3 6.1.4 -6.1.5 6.1.6 6.1.7 6.1.8 -6.1.9 6.2.0 6.2.1 6.2.10 @@ -94,7 +91,9 @@ 6.2.2 6.2.3 6.2.4 +6.2.5 6.2.6 +6.2.7 6.2.8 6.2.9 7.0.0 @@ -103,7 +102,7 @@ 7.0.11 7.0.12 7.0.13 -7.0.14 +7.0.15 7.0.2 7.0.3 7.0.4 @@ -117,16 +116,19 @@ 7.1.10 7.1.11 7.1.12 +7.1.13 7.1.2 7.1.3 7.1.4 7.1.5 +7.1.6 7.1.7 7.1.8 7.1.9 7.2.0 7.2.1 7.2.10 +7.2.11 7.2.2 7.2.3 7.2.4 @@ -144,12 +146,14 @@ 7.3.6 7.3.7 7.3.8 +7.3.9 7.4.0 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 +7.4.6 7.5.0 7.5.1 7.5.2 @@ -158,3 +162,5 @@ 7.5.5 7.6.0 7.6.1 +7.6.2 +7.7.0 diff --git a/scripts/utils.sh b/scripts/utils.sh index 6e1057ad19..dc031bf668 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -13,7 +13,7 @@ then trap cleanup-workaround-file EXIT test_file="$PWD/$0" filename=$(basename $test_file) - if [ "$filename" != "playground-command" ] + if [[ "$filename" != "playground-command"* ]] then playground state set run.test_file "$test_file" playground state set run.connector_type "$(get_connector_type | tr -d '\n')" From a38903759ecaa782e8e9b64620e8e2c6b3ca57c9 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Sep 2024 15:57:30 +0200 Subject: [PATCH 002/659] Update docker-compose.plaintext.proxy.yml --- .../docker-compose.plaintext.proxy.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/connect/connect-azure-blob-storage-sink/docker-compose.plaintext.proxy.yml b/connect/connect-azure-blob-storage-sink/docker-compose.plaintext.proxy.yml index 6b4f276df8..2349322cb5 100644 --- a/connect/connect-azure-blob-storage-sink/docker-compose.plaintext.proxy.yml +++ b/connect/connect-azure-blob-storage-sink/docker-compose.plaintext.proxy.yml @@ -15,4 +15,6 @@ services: - ../../connect/connect-azure-blob-storage-sink/data:/data environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-azure-blob-storage - # dns: 0.0.0.0 \ No newline at end of file + # https://support.confluent.io/hc/en-us/articles/16480297311124-How-to-bypass-Azure-Blob-Storage-sink-connector-failing-with-InaccessibleObjectException + KAFKA_OPTS: --add-opens=java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED + # dns: 0.0.0.0 From ecf4a1a9f8fa9426d6a6d1dbc089b0bed68aa43b Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Sep 2024 15:57:43 +0200 Subject: [PATCH 003/659] Update docker-compose.plaintext.yml --- .../docker-compose.plaintext.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/connect/connect-azure-blob-storage-sink/docker-compose.plaintext.yml b/connect/connect-azure-blob-storage-sink/docker-compose.plaintext.yml index da83acd1d2..c0a977ec13 100644 --- a/connect/connect-azure-blob-storage-sink/docker-compose.plaintext.yml +++ b/connect/connect-azure-blob-storage-sink/docker-compose.plaintext.yml @@ -4,4 +4,6 @@ services: volumes: - ../../connect/connect-azure-blob-storage-sink/data:/data environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-azure-blob-storage \ No newline at end of file + CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-azure-blob-storage + # https://support.confluent.io/hc/en-us/articles/16480297311124-How-to-bypass-Azure-Blob-Storage-sink-connector-failing-with-InaccessibleObjectException + KAFKA_OPTS: --add-opens=java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED From 874d5e75548a95ca71a167bd364a1c979a3cc41e Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Sep 2024 15:58:22 +0200 Subject: [PATCH 004/659] Update docker-compose.plaintext.backup-and-restore.yml --- .../docker-compose.plaintext.backup-and-restore.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/connect/connect-azure-blob-storage-source/docker-compose.plaintext.backup-and-restore.yml b/connect/connect-azure-blob-storage-source/docker-compose.plaintext.backup-and-restore.yml index 4de8073f93..4bae8fa0e3 100644 --- a/connect/connect-azure-blob-storage-source/docker-compose.plaintext.backup-and-restore.yml +++ b/connect/connect-azure-blob-storage-source/docker-compose.plaintext.backup-and-restore.yml @@ -4,4 +4,6 @@ services: volumes: - ../../connect/connect-azure-blob-storage-source/data:/data environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-azure-blob-storage-source,/usr/share/confluent-hub-components/confluentinc-kafka-connect-azure-blob-storage \ No newline at end of file + CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-azure-blob-storage-source,/usr/share/confluent-hub-components/confluentinc-kafka-connect-azure-blob-storage + # https://support.confluent.io/hc/en-us/articles/16480297311124-How-to-bypass-Azure-Blob-Storage-sink-connector-failing-with-InaccessibleObjectException + KAFKA_OPTS: --add-opens=java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED From 8390726c1c071724181a588b0700b6b7dec061f9 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Sep 2024 15:58:34 +0200 Subject: [PATCH 005/659] Update docker-compose.plaintext.proxy.backup-and-restore.yml --- .../docker-compose.plaintext.proxy.backup-and-restore.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/connect/connect-azure-blob-storage-source/docker-compose.plaintext.proxy.backup-and-restore.yml b/connect/connect-azure-blob-storage-source/docker-compose.plaintext.proxy.backup-and-restore.yml index 36899c26a4..280e262491 100644 --- a/connect/connect-azure-blob-storage-source/docker-compose.plaintext.proxy.backup-and-restore.yml +++ b/connect/connect-azure-blob-storage-source/docker-compose.plaintext.proxy.backup-and-restore.yml @@ -14,4 +14,6 @@ services: volumes: - ../../connect/connect-azure-blob-storage-source/data:/data environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-azure-blob-storage-source,/usr/share/confluent-hub-components/confluentinc-kafka-connect-azure-blob-storage \ No newline at end of file + CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-azure-blob-storage-source,/usr/share/confluent-hub-components/confluentinc-kafka-connect-azure-blob-storage + # https://support.confluent.io/hc/en-us/articles/16480297311124-How-to-bypass-Azure-Blob-Storage-sink-connector-failing-with-InaccessibleObjectException + KAFKA_OPTS: --add-opens=java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED From ef592edf32cc8dfccf1795c3dfeaf73d7ba98dae Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Sep 2024 15:59:46 +0200 Subject: [PATCH 006/659] Update connect-onprem-to-cloud.sh --- ccloud/replicator/connect-onprem-to-cloud.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ccloud/replicator/connect-onprem-to-cloud.sh b/ccloud/replicator/connect-onprem-to-cloud.sh index 3e6382e3ff..895571f4f1 100755 --- a/ccloud/replicator/connect-onprem-to-cloud.sh +++ b/ccloud/replicator/connect-onprem-to-cloud.sh @@ -29,16 +29,16 @@ playground connector create-or-update --connector replicate-onprem-to-cloud << "src.consumer.group.id": "replicate-onprem-to-cloud", "src.kafka.bootstrap.servers": "broker:9092", "dest.kafka.ssl.endpoint.identification.algorithm":"https", - "dest.kafka.bootstrap.servers": "\${file:/data:bootstrap.servers}", + "dest.kafka.bootstrap.servers": "\${file:/datacloud:bootstrap.servers}", "dest.kafka.security.protocol" : "SASL_SSL", - "dest.kafka.sasl.jaas.config": "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/data:sasl.username}\" password=\"\${file:/data:sasl.password}\";", + "dest.kafka.sasl.jaas.config": "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/datacloud:sasl.username}\" password=\"\${file:/datacloud:sasl.password}\";", "dest.kafka.sasl.mechanism":"PLAIN", "dest.kafka.request.timeout.ms":"20000", "dest.kafka.retry.backoff.ms":"500", "confluent.topic.ssl.endpoint.identification.algorithm" : "https", "confluent.topic.sasl.mechanism" : "PLAIN", - "confluent.topic.bootstrap.servers": "\${file:/data:bootstrap.servers}", - "confluent.topic.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/data:sasl.username}\" password=\"\${file:/data:sasl.password}\";", + "confluent.topic.bootstrap.servers": "\${file:/datacloud:bootstrap.servers}", + "confluent.topic.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/datacloud:sasl.username}\" password=\"\${file:/datacloud:sasl.password}\";", "confluent.topic.security.protocol" : "SASL_SSL", "confluent.topic.replication.factor": "3", "provenance.header.enable": true, @@ -50,4 +50,4 @@ EOF log "Verify we have received the data in products topic" -playground topic consume --topic products --min-expected-messages 10 --timeout 60 \ No newline at end of file +playground topic consume --topic products --min-expected-messages 10 --timeout 60 From 0f972f94cabb6ced0b57e14207ae60391ee37d52 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Sep 2024 16:00:02 +0200 Subject: [PATCH 007/659] Update connect-onprem-to-cloud-avro.sh --- ccloud/replicator/connect-onprem-to-cloud-avro.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ccloud/replicator/connect-onprem-to-cloud-avro.sh b/ccloud/replicator/connect-onprem-to-cloud-avro.sh index aaa4531af1..081bc70949 100755 --- a/ccloud/replicator/connect-onprem-to-cloud-avro.sh +++ b/ccloud/replicator/connect-onprem-to-cloud-avro.sh @@ -51,20 +51,20 @@ playground connector create-or-update --connector replicate-onprem-to-cloud << "value.converter": "io.confluent.connect.avro.AvroConverter", "value.converter.schema.registry.url": "$SCHEMA_REGISTRY_URL", - "value.converter.basic.auth.user.info": "\${file:/data:schema.registry.basic.auth.user.info}", + "value.converter.basic.auth.user.info": "\${file:/datacloud:schema.registry.basic.auth.user.info}", "value.converter.basic.auth.credentials.source": "USER_INFO", "dest.kafka.ssl.endpoint.identification.algorithm":"https", - "dest.kafka.bootstrap.servers": "\${file:/data:bootstrap.servers}", + "dest.kafka.bootstrap.servers": "\${file:/datacloud:bootstrap.servers}", "dest.kafka.security.protocol" : "SASL_SSL", - "dest.kafka.sasl.jaas.config": "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/data:sasl.username}\" password=\"\${file:/data:sasl.password}\";", + "dest.kafka.sasl.jaas.config": "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/datacloud:sasl.username}\" password=\"\${file:/datacloud:sasl.password}\";", "dest.kafka.sasl.mechanism":"PLAIN", "dest.kafka.request.timeout.ms":"20000", "dest.kafka.retry.backoff.ms":"500", "confluent.topic.ssl.endpoint.identification.algorithm" : "https", "confluent.topic.sasl.mechanism" : "PLAIN", - "confluent.topic.bootstrap.servers": "\${file:/data:bootstrap.servers}", - "confluent.topic.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/data:sasl.username}\" password=\"\${file:/data:sasl.password}\";", + "confluent.topic.bootstrap.servers": "\${file:/datacloud:bootstrap.servers}", + "confluent.topic.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/datacloud:sasl.username}\" password=\"\${file:/datacloud:sasl.password}\";", "confluent.topic.security.protocol" : "SASL_SSL", "confluent.topic.replication.factor": "3", "provenance.header.enable": true, @@ -78,4 +78,4 @@ EOF # "value.converter.connect.meta.data": false log "Verify we have received the data in products-avro topic" -playground topic consume --topic products-avro --min-expected-messages 3 --timeout 60 \ No newline at end of file +playground topic consume --topic products-avro --min-expected-messages 3 --timeout 60 From 0de524c0a41c41e1c510ec1237d40f3f8b405f96 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Sep 2024 16:00:21 +0200 Subject: [PATCH 008/659] Update connect-onprem-to-cloud-avro-with-sr-basic-auth.sh --- ...nect-onprem-to-cloud-avro-with-sr-basic-auth.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ccloud/replicator/connect-onprem-to-cloud-avro-with-sr-basic-auth.sh b/ccloud/replicator/connect-onprem-to-cloud-avro-with-sr-basic-auth.sh index 77c9c93404..340eff4669 100755 --- a/ccloud/replicator/connect-onprem-to-cloud-avro-with-sr-basic-auth.sh +++ b/ccloud/replicator/connect-onprem-to-cloud-avro-with-sr-basic-auth.sh @@ -39,27 +39,27 @@ playground connector create-or-update --connector replicate-onprem-to-cloud << "src.kafka.bootstrap.servers": "broker:9092", "dest.kafka.ssl.endpoint.identification.algorithm":"https", - "dest.kafka.bootstrap.servers": "\${file:/data:bootstrap.servers}", + "dest.kafka.bootstrap.servers": "\${file:/datacloud:bootstrap.servers}", "dest.kafka.security.protocol" : "SASL_SSL", - "dest.kafka.sasl.jaas.config": "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/data:sasl.username}\" password=\"\${file:/data:sasl.password}\";", + "dest.kafka.sasl.jaas.config": "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/datacloud:sasl.username}\" password=\"\${file:/datacloud:sasl.password}\";", "dest.kafka.sasl.mechanism":"PLAIN", "dest.kafka.request.timeout.ms":"20000", "dest.kafka.retry.backoff.ms":"500", "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "$SCHEMA_REGISTRY_URL", - "key.converter.basic.auth.user.info": "\${file:/data:schema.registry.basic.auth.user.info}", + "key.converter.basic.auth.user.info": "\${file:/datacloud:schema.registry.basic.auth.user.info}", "key.converter.basic.auth.credentials.source": "USER_INFO", "value.converter": "io.confluent.connect.avro.AvroConverter", "value.converter.schema.registry.url": "$SCHEMA_REGISTRY_URL", - "value.converter.basic.auth.user.info": "\${file:/data:schema.registry.basic.auth.user.info}", + "value.converter.basic.auth.user.info": "\${file:/datacloud:schema.registry.basic.auth.user.info}", "value.converter.basic.auth.credentials.source": "USER_INFO", "confluent.topic.ssl.endpoint.identification.algorithm" : "https", "confluent.topic.sasl.mechanism" : "PLAIN", - "confluent.topic.bootstrap.servers": "\${file:/data:bootstrap.servers}", - "confluent.topic.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/data:sasl.username}\" password=\"\${file:/data:sasl.password}\";", + "confluent.topic.bootstrap.servers": "\${file:/datacloud:bootstrap.servers}", + "confluent.topic.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/datacloud:sasl.username}\" password=\"\${file:/datacloud:sasl.password}\";", "confluent.topic.security.protocol" : "SASL_SSL", "confluent.topic.replication.factor": "3", "provenance.header.enable": true, @@ -73,4 +73,4 @@ EOF # "value.converter.connect.meta.data": false log "Verify we have received the data in products-avro topic" -playground topic consume --topic products-avro --min-expected-messages 3 --timeout 60 \ No newline at end of file +playground topic consume --topic products-avro --min-expected-messages 3 --timeout 60 From 8a1f39c6f46cbfdd5475f6d9dd36c11ae3dfaa15 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Sep 2024 16:01:35 +0200 Subject: [PATCH 009/659] Update cli_function.sh --- scripts/cli/src/lib/cli_function.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/cli/src/lib/cli_function.sh b/scripts/cli/src/lib/cli_function.sh index 3feb4a8757..372a69b934 100644 --- a/scripts/cli/src/lib/cli_function.sh +++ b/scripts/cli/src/lib/cli_function.sh @@ -839,7 +839,7 @@ function add_connector_config_based_on_environment () { # log "replacing $prefix config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"$prefix.bootstrap.servers\"] = \"\${file:/data:bootstrap.servers}\" | .[\"$prefix.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"\${file:/data:sasl.username}\\\" password=\\\"\${file:/data:sasl.password}\\\";\" | .[\"$prefix.security.protocol\"] = \"SASL_SSL\" | .[\"$prefix.sasl.mechanism\"] = \"PLAIN\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"$prefix.bootstrap.servers\"] = \"\${file:/datacloud:bootstrap.servers}\" | .[\"$prefix.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"\${file:/datacloud:sasl.username}\\\" password=\\\"\${file:/datacloud:sasl.password}\\\";\" | .[\"$prefix.security.protocol\"] = \"SASL_SSL\" | .[\"$prefix.sasl.mechanism\"] = \"PLAIN\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) if [ "$prefix" == "confluent.topic" ] @@ -858,7 +858,7 @@ function add_connector_config_based_on_environment () { # log "replacing $prefix.converter.schema.registry.url config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"$prefix.converter.schema.registry.url\"] = \"$SCHEMA_REGISTRY_URL\" | .[\"$prefix.converter.basic.auth.user.info\"] = \"\${file:/data:schema.registry.basic.auth.user.info}\" | .[\"$prefix.converter.basic.auth.credentials.source\"] = \"USER_INFO\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"$prefix.converter.schema.registry.url\"] = \"$SCHEMA_REGISTRY_URL\" | .[\"$prefix.converter.basic.auth.user.info\"] = \"\${file:/datacloud:schema.registry.basic.auth.user.info}\" | .[\"$prefix.converter.basic.auth.credentials.source\"] = \"USER_INFO\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi done @@ -868,7 +868,7 @@ function add_connector_config_based_on_environment () { # log "replacing database.history.kafka.bootstrap.servers config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"database.history.kafka.bootstrap.servers\"] = \"\${file:/data:bootstrap.servers}\" | .[\"database.history.producer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"\${file:/data:sasl.username}\\\" password=\\\"\${file:/data:sasl.password}\\\";\" | .[\"database.history.producer.security.protocol\"] = \"SASL_SSL\" | .[\"database.history.producer.sasl.mechanism\"] = \"PLAIN\" | .[\"database.history.consumer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"\${file:/data:sasl.username}\\\" password=\\\"\${file:/data:sasl.password}\\\";\" | .[\"database.history.consumer.security.protocol\"] = \"SASL_SSL\" | .[\"database.history.consumer.sasl.mechanism\"] = \"PLAIN\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"database.history.kafka.bootstrap.servers\"] = \"\${file:/datacloud:bootstrap.servers}\" | .[\"database.history.producer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"\${file:/datacloud:sasl.username}\\\" password=\\\"\${file:/datacloud:sasl.password}\\\";\" | .[\"database.history.producer.security.protocol\"] = \"SASL_SSL\" | .[\"database.history.producer.sasl.mechanism\"] = \"PLAIN\" | .[\"database.history.consumer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"\${file:/datacloud:sasl.username}\\\" password=\\\"\${file:/datacloud:sasl.password}\\\";\" | .[\"database.history.consumer.security.protocol\"] = \"SASL_SSL\" | .[\"database.history.consumer.sasl.mechanism\"] = \"PLAIN\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi @@ -877,7 +877,7 @@ function add_connector_config_based_on_environment () { # log "replacing schema.history.internal.kafka.bootstrap.servers config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"schema.history.internal.kafka.bootstrap.servers\"] = \"\${file:/data:bootstrap.servers}\" | .[\"schema.history.internal.producer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"\${file:/data:sasl.username}\\\" password=\\\"\${file:/data:sasl.password}\\\";\" | .[\"schema.history.internal.producer.security.protocol\"] = \"SASL_SSL\" | .[\"schema.history.internal.producer.sasl.mechanism\"] = \"PLAIN\" | .[\"schema.history.internal.consumer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"\${file:/data:sasl.username}\\\" password=\\\"\${file:/data:sasl.password}\\\";\" | .[\"schema.history.internal.consumer.security.protocol\"] = \"SASL_SSL\" | .[\"schema.history.internal.consumer.sasl.mechanism\"] = \"PLAIN\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"schema.history.internal.kafka.bootstrap.servers\"] = \"\${file:/datacloud:bootstrap.servers}\" | .[\"schema.history.internal.producer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"\${file:/datacloud:sasl.username}\\\" password=\\\"\${file:/datacloud:sasl.password}\\\";\" | .[\"schema.history.internal.producer.security.protocol\"] = \"SASL_SSL\" | .[\"schema.history.internal.producer.sasl.mechanism\"] = \"PLAIN\" | .[\"schema.history.internal.consumer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"\${file:/datacloud:sasl.username}\\\" password=\\\"\${file:/datacloud:sasl.password}\\\";\" | .[\"schema.history.internal.consumer.security.protocol\"] = \"SASL_SSL\" | .[\"schema.history.internal.consumer.sasl.mechanism\"] = \"PLAIN\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi @@ -886,7 +886,7 @@ function add_connector_config_based_on_environment () { # log "replacing reporter.bootstrap.servers config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"reporter.bootstrap.servers\"] = \"\${file:/data:bootstrap.servers}\" | .[\"reporter.result.topic.replication.factor\"] = \"3\" | .[\"reporter.error.topic.replication.factor\"] = \"3\" | .[\"reporter.admin.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"\${file:/data:sasl.username}\\\" password=\\\"\${file:/data:sasl.password}\\\";\" | .[\"reporter.admin.security.protocol\"] = \"SASL_SSL\" | .[\"reporter.admin.sasl.mechanism\"] = \"PLAIN\" | .[\"reporter.producer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"\${file:/data:sasl.username}\\\" password=\\\"\${file:/data:sasl.password}\\\";\" | .[\"reporter.producer.security.protocol\"] = \"SASL_SSL\" | .[\"reporter.producer.sasl.mechanism\"] = \"PLAIN\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"reporter.bootstrap.servers\"] = \"\${file:/datacloud:bootstrap.servers}\" | .[\"reporter.result.topic.replication.factor\"] = \"3\" | .[\"reporter.error.topic.replication.factor\"] = \"3\" | .[\"reporter.admin.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"\${file:/datacloud:sasl.username}\\\" password=\\\"\${file:/datacloud:sasl.password}\\\";\" | .[\"reporter.admin.security.protocol\"] = \"SASL_SSL\" | .[\"reporter.admin.sasl.mechanism\"] = \"PLAIN\" | .[\"reporter.producer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"\${file:/datacloud:sasl.username}\\\" password=\\\"\${file:/datacloud:sasl.password}\\\";\" | .[\"reporter.producer.security.protocol\"] = \"SASL_SSL\" | .[\"reporter.producer.sasl.mechanism\"] = \"PLAIN\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi ;; @@ -1559,4 +1559,4 @@ function check_for_ec2_instance_running() { log "🤑👛 you have an ec2 instance $instance running" done fi -} \ No newline at end of file +} From 1fb0016c9993c4aa9fc743f93ef636e9dae0f53f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Sep 2024 16:02:04 +0200 Subject: [PATCH 010/659] Update get-number-records.sh --- scripts/cli/src/commands/topic/get-number-records.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/cli/src/commands/topic/get-number-records.sh b/scripts/cli/src/commands/topic/get-number-records.sh index c14f99465a..792164ea77 100644 --- a/scripts/cli/src/commands/topic/get-number-records.sh +++ b/scripts/cli/src/commands/topic/get-number-records.sh @@ -101,7 +101,12 @@ do docker exec $container timeout 15 kafka-console-consumer --bootstrap-server broker:9092 --topic $topic $security --from-beginning --timeout-ms 15000 2>/dev/null | wc -l | tr -d ' ' set -e else - docker exec $container kafka-run-class kafka.tools.GetOffsetShell --broker-list broker:9092 $security --topic $topic --time -1 | awk -F ":" '{sum += $3} END {print sum}' + class_name="kafka.tools.GetOffsetShell" + if version_gt $tag "7.6.9" + then + class_name="org.apache.kafka.tools.GetOffsetShell" + fi + docker exec $container kafka-run-class $class_name --broker-list broker:9092 $security --topic $topic --time -1 | awk -F ":" '{sum += $3} END {print sum}' fi fi -done \ No newline at end of file +done From c00b1147d62b2ccf6834cb7e1869d9077dd18cab Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Sep 2024 16:02:24 +0200 Subject: [PATCH 011/659] Update heap-dump.sh --- scripts/cli/src/commands/debug/heap-dump.sh | 55 ++++++++++++++------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/scripts/cli/src/commands/debug/heap-dump.sh b/scripts/cli/src/commands/debug/heap-dump.sh index 3f6722a3d0..441d5c71d3 100644 --- a/scripts/cli/src/commands/debug/heap-dump.sh +++ b/scripts/cli/src/commands/debug/heap-dump.sh @@ -1,5 +1,6 @@ container="${args[--container]}" -filename="heap-dump-$container-`date '+%Y-%m-%d-%H-%M-%S'`.hprof" +live="${args[--live]}" +histo="${args[--histo]}" set +e docker exec $container type jmap > /dev/null 2>&1 @@ -8,23 +9,41 @@ then logerror "❌ jmap is not installed on container $container" exit 1 fi -set -e -log "🎯 Taking heap dump on container ${container} for pid 1" -docker exec $container jmap -dump:live,format=b,file=/tmp/${filename} 1 -if [ $? -eq 0 ] + +if [[ -n "$histo" ]] then - log "👻 heap dump is available at ${filename}" - docker cp ${container}:/tmp/${filename} ${filename} - # if [[ $(type -f wireshark 2>&1) =~ "not found" ]] - # then - # logwarn "🦈 wireshark is not installed, grab it at https://www.wireshark.org/" - # exit 0 - # else - # log "🦈 Opening ${filename} with wireshark" - # wireshark ${filename} - # fi + filename="heap-dump-$container-histo-`date '+%Y-%m-%d-%H-%M-%S'`.txt" + set -e + if [[ -n "$live" ]] + then + log "📊 Taking histo (with live option) heap dump on container ${container}" + docker exec $container jmap -histo:live 1 > /tmp/${filename} + else + log "📊 Taking histo (without live option) heap dump on container ${container}" + docker exec $container jmap -histo 1 > /tmp/${filename} + fi + if [ $? -eq 0 ] + then + log "👻 heap dump is available at /tmp/${filename}" + else + logerror "❌ Failed to take heap dump" + fi else - logerror "❌ Failed to take heap dump" + filename="heap-dump-$container-`date '+%Y-%m-%d-%H-%M-%S'`.hprof" + set -e + if [[ -n "$live" ]] + then + log "🎯 Taking heap dump (with live option) on container ${container}" + docker exec $container jmap -dump:live,format=b,file=/tmp/${filename} 1 + else + log "🎯 Taking heap dump (without live option) on container ${container}" + docker exec $container jmap -dump:live,format=b,file=/tmp/${filename} 1 + fi + if [ $? -eq 0 ] + then + log "👻 heap dump is available at ${filename}" + docker cp ${container}:/tmp/${filename} ${filename} + else + logerror "❌ Failed to take heap dump" + fi fi - - From cea2e75fb0a954d0d98bec9e7bb8f00d60de9e4f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Sep 2024 16:03:10 +0200 Subject: [PATCH 012/659] Update snippets.sh --- scripts/cli/src/commands/connector/snippets.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/cli/src/commands/connector/snippets.sh b/scripts/cli/src/commands/connector/snippets.sh index 611e0e7ac8..f1c786f2c3 100644 --- a/scripts/cli/src/commands/connector/snippets.sh +++ b/scripts/cli/src/commands/connector/snippets.sh @@ -91,11 +91,11 @@ then echo -e " \"key.converter\": \"$converter_class\"," >> $converter_file echo -e " \"key.converter.schema.registry.url\": \"$SCHEMA_REGISTRY_URL\"," >> $converter_file echo -e " \"key.converter.basic.auth.credentials.source\": \"USER_INFO\"," >> $converter_file - echo -e " \"key.converter.basic.auth.user.info\": \"\${file:/data:schema.registry.basic.auth.user.info}\"," >> $converter_file + echo -e " \"key.converter.basic.auth.user.info\": \"\${file:/datacloud:schema.registry.basic.auth.user.info}\"," >> $converter_file echo -e " \"value.converter\": \"$converter_class\"," >> $converter_file echo -e " \"value.converter.schema.registry.url\": \"$SCHEMA_REGISTRY_URL\"," >> $converter_file echo -e " \"value.converter.basic.auth.credentials.source\": \"USER_INFO\"," >> $converter_file - echo -e " \"value.converter.basic.auth.user.info\": \"\${file:/data:schema.registry.basic.auth.user.info}\"," >> $converter_file + echo -e " \"value.converter.basic.auth.user.info\": \"\${file:/datacloud:schema.registry.basic.auth.user.info}\"," >> $converter_file ;; sasl-ssl|2way-ssl) @@ -166,4 +166,4 @@ then log "📋 config has been copied to the clipboard (disable with 'playground config set clipboard false')" fi fi -fi \ No newline at end of file +fi From 2820d2499c27c159de32e4b52a12635845265eaa Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Sep 2024 16:03:44 +0200 Subject: [PATCH 013/659] Update create-or-update.sh --- .../commands/connector/create-or-update.sh | 30 ++++++------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/scripts/cli/src/commands/connector/create-or-update.sh b/scripts/cli/src/commands/connector/create-or-update.sh index 1a54ab6600..818c5b6f03 100644 --- a/scripts/cli/src/commands/connector/create-or-update.sh +++ b/scripts/cli/src/commands/connector/create-or-update.sh @@ -153,29 +153,17 @@ then exit 1 fi - is_valid=1 - for row in $(echo "$curl_output" | jq -r '.configs[] | @base64'); do - _jq() { - echo ${row} | base64 -d | jq -r ${1} - } + # Check if there were any errors + has_errors=$(echo "$curl_output" | jq '.configs[] | select(.value.errors | length > 0) | length' | tr -d '\n') - name=$(_jq '.value.name') - value=$(_jq '.value.value') - errors=$(_jq '.value.errors') - - if [ "$(echo "$errors" | jq 'length')" -gt 0 ] - then - is_valid=0 - logerror "❌ validation error for config <$name=$value>" - echo "$errors" | jq . - fi - done - - if [ $is_valid -eq 1 ] + if [[ "$has_errors" -gt 0 ]] then - log "✅ $connector_type connector config is valid !" - else + output=$(echo "$curl_output" | jq -r '.configs[] | select(.value.errors | length > 0) | .value.name + " ->> " + (.value.errors | to_entries | map("\(.value|tostring)") | join(", "))') + logerror "❌ Validation errors found in connector config\n$output" + exit 1 + else + log "✅ $connector_type connector config is valid !" fi fi @@ -307,4 +295,4 @@ then logwarn "⏭️ --wait-for-zero-lag is set but $connector_type connector ${connector}${maybe_id} is not a sink" fi playground connector show-lag --connector $connector -fi \ No newline at end of file +fi From ac4617edd52be3d38379ffba31d81be4370fd2d4 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Sep 2024 16:05:18 +0200 Subject: [PATCH 014/659] Update bashly.yml --- scripts/cli/src/bashly.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index 1cc8dbd370..cb8d03c030 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -1596,8 +1596,18 @@ commands: 👻 Take a heap dump 🔖 It will save output to a .hprof file. VisualVM (https://visualvm.github.io/) or MAT (https://www.eclipse.org/mat/) can be used to read the file. + + It will run a full gc first. If you don't want this, use flags: - *container + - long: --live + required: false + help: |- + 🧬 dump only live objects; if not specified, all objects in the heap are dumped + - long: --histo + required: false + help: |- + 📊 print histogram of java object heap examples: - playground debug heap-dump - playground debug heap-dump --container broker @@ -3473,4 +3483,4 @@ commands: - name: ec2-to-local help: 👈 Sync ec2 instance reproduction-models folder to local flags: - - *instance \ No newline at end of file + - *instance From fa8d5a0b5b35212ba70dcbc71ffca44a3077866d Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 10 Sep 2024 17:53:49 +0200 Subject: [PATCH 015/659] Features3 (#4) * reproduction-models * fix self certs * 2.00.076.00.20240701.1 --- .gitignore | 3 ++- ...bezium-sqlserver-source-repro-pipeline-example.sh | 4 ++-- ...y-managed-debezium-legacy-sqlserver-source-ssl.sh | 4 ++-- ...fully-managed-debezium-legacy-sqlserver-source.sh | 4 ++-- ...fully-managed-debezium-v2-sqlserver-source-ssl.sh | 4 ++-- .../fully-managed-debezium-v2-sqlserver-source.sh | 4 ++-- .../fully-managed-sqlserver-microsoft-sink.sh | 2 +- .../fully-managed-sqlserver-source.sh | 4 ++-- connect/connect-debezium-sqlserver-source/README.md | 4 ++-- ...debezium-sqlserver-source-incremental-snapshot.sh | 12 ++++++------ .../debezium-sqlserver-source-ssl.sh | 4 ++-- .../debezium-sqlserver-source-standalone-worker.sh | 4 ++-- .../debezium-sqlserver-source.sh | 4 ++-- .../docker-compose.plaintext.yml | 2 +- .../docker-compose.plaintext.yml | 2 +- connect/connect-jdbc-sqlserver-sink/README.md | 2 +- .../sqlserver-jtds-sink-ssl.sh | 2 +- .../sqlserver-jtds-sink.sh | 2 +- .../sqlserver-microsoft-sink-ssl.sh | 2 +- .../sqlserver-microsoft-sink.sh | 2 +- connect/connect-jdbc-sqlserver-source/README.md | 4 ++-- .../sqlserver-jtds-ssl.sh | 4 ++-- .../connect-jdbc-sqlserver-source/sqlserver-jtds.sh | 4 ++-- .../sqlserver-microsoft-ssl.sh | 4 ++-- .../sqlserver-microsoft.sh | 4 ++-- .../docker-compose.plaintext.yml | 2 +- 26 files changed, 47 insertions(+), 46 deletions(-) diff --git a/.gitignore b/.gitignore index 86b9a44122..5cdd8df5b3 100644 --- a/.gitignore +++ b/.gitignore @@ -75,4 +75,5 @@ playground_config.ini .ccloud .connector_config hsperfdata_appuser -*.lck \ No newline at end of file +*.lck +reproduction-models \ No newline at end of file diff --git a/academy/connect-connect-debezium-sqlserver-source/debezium-sqlserver-source-repro-pipeline-example.sh b/academy/connect-connect-debezium-sqlserver-source/debezium-sqlserver-source-repro-pipeline-example.sh index 7dd20d8cd5..048ecdd366 100755 --- a/academy/connect-connect-debezium-sqlserver-source/debezium-sqlserver-source-repro-pipeline-example.sh +++ b/academy/connect-connect-debezium-sqlserver-source/debezium-sqlserver-source-repro-pipeline-example.sh @@ -16,7 +16,7 @@ playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker- log "Create table" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -73,7 +73,7 @@ EOF sleep 5 -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh b/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh index c7f1715a2c..0c2e641ac2 100755 --- a/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh +++ b/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh @@ -99,7 +99,7 @@ do done log "Create table" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -153,7 +153,7 @@ playground connector create-or-update --connector $connector_name << EOF EOF wait_for_ccloud_connector_up $connector_name 180 -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source.sh b/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source.sh index acaeaa8503..f2d85456d6 100755 --- a/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source.sh +++ b/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source.sh @@ -74,7 +74,7 @@ do done log "Create table" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -127,7 +127,7 @@ EOF wait_for_ccloud_connector_up $connector_name 180 -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh b/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh index 3a1768f61a..378c31809f 100755 --- a/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh +++ b/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh @@ -97,7 +97,7 @@ do done log "Create table" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -152,7 +152,7 @@ playground connector create-or-update --connector $connector_name << EOF EOF wait_for_ccloud_connector_up $connector_name 180 -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source.sh b/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source.sh index 17672e394f..5ac87acda9 100755 --- a/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source.sh +++ b/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source.sh @@ -74,7 +74,7 @@ do done log "Create table" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -127,7 +127,7 @@ EOF wait_for_ccloud_connector_up $connector_name 180 -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/ccloud/fm-jdbc-sqlserver-sink/fully-managed-sqlserver-microsoft-sink.sh b/ccloud/fm-jdbc-sqlserver-sink/fully-managed-sqlserver-microsoft-sink.sh index aedfe01301..0a3c902c94 100755 --- a/ccloud/fm-jdbc-sqlserver-sink/fully-managed-sqlserver-microsoft-sink.sh +++ b/ccloud/fm-jdbc-sqlserver-sink/fully-managed-sqlserver-microsoft-sink.sh @@ -131,7 +131,7 @@ EOF sleep 5 log "Show content of sqlserver_table table:" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF select * from sqlserver_table GO EOF diff --git a/ccloud/fm-jdbc-sqlserver-source/fully-managed-sqlserver-source.sh b/ccloud/fm-jdbc-sqlserver-source/fully-managed-sqlserver-source.sh index 5abf4af173..9673ff1276 100755 --- a/ccloud/fm-jdbc-sqlserver-source/fully-managed-sqlserver-source.sh +++ b/ccloud/fm-jdbc-sqlserver-source/fully-managed-sqlserver-source.sh @@ -25,7 +25,7 @@ docker compose up -d --quiet-pull sleep 5 log "Create table" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -105,7 +105,7 @@ playground connector create-or-update --connector $connector_name << EOF EOF wait_for_ccloud_connector_up $connector_name 180 -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-debezium-sqlserver-source/README.md b/connect/connect-debezium-sqlserver-source/README.md index 182484121c..2f396b9cee 100644 --- a/connect/connect-debezium-sqlserver-source/README.md +++ b/connect/connect-debezium-sqlserver-source/README.md @@ -24,7 +24,7 @@ $ just use command and search for debezium-sqlserver-source.sh Load inventory.sql to SQL Server ```bash -$ cat ../../connect/connect-debezium-sqlserver-source/inventory.sql | docker exec -i sqlserver bash -c '/opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password!' +$ cat ../../connect/connect-debezium-sqlserver-source/inventory.sql | docker exec -i sqlserver bash -c '/opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password!' ``` @@ -58,7 +58,7 @@ $ curl -X PUT \ Insert one more row: ```bash -$ docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +$ docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-incremental-snapshot.sh b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-incremental-snapshot.sh index 14c650771b..ac84946bef 100755 --- a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-incremental-snapshot.sh +++ b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-incremental-snapshot.sh @@ -15,7 +15,7 @@ playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker- log "Create table" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -43,7 +43,7 @@ EOF # https://debezium.io/documentation/reference/1.9/configuration/signalling.html#sending-signals-to-a-debezium-connector log "Creating a signaling data collection" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; CREATE TABLE debezium_signal (id VARCHAR(42) PRIMARY KEY, type VARCHAR(32) NOT NULL, data VARCHAR(2048) NULL); EXEC sys.sp_cdc_enable_table @source_schema = 'dbo', @source_name = 'debezium_signal', @role_name = NULL, @supports_net_changes = 0; @@ -79,7 +79,7 @@ EOF sleep 5 log "Insert another row" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO @@ -90,7 +90,7 @@ playground topic consume --topic server1.testDB.dbo.customers --min-expected-mes log "Add another table customers2" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; CREATE TABLE customers2 ( id INTEGER IDENTITY(1001,1) NOT NULL PRIMARY KEY, @@ -142,7 +142,7 @@ playground connector create-or-update --connector debezium-sqlserver-source << EOF log "Add another table customers2" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers2(first_name,last_name,email) VALUES ('Anne2','Kretchmar2','annek2@noanswer.org'); @@ -155,7 +155,7 @@ log "Verifying topic server1.testDB.dbo.customers2 : there will be only the new playground topic consume --topic server1.testDB.dbo.customers2 --min-expected-messages 1 --timeout 60 log "Trigger Ad hoc snapshot" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO debezium_signal (id, type, data) VALUES('captain adhoc $RANDOM', 'execute-snapshot', '{"data-collections": ["testDB.dbo.customers2"], "type":"incremental"}'); GO diff --git a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh index a512e970a4..4c4aa078b6 100755 --- a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh +++ b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh @@ -64,7 +64,7 @@ playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker- log "Create table" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -123,7 +123,7 @@ EOF sleep 5 -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-standalone-worker.sh b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-standalone-worker.sh index 715de126b5..20767f916f 100755 --- a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-standalone-worker.sh +++ b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-standalone-worker.sh @@ -17,7 +17,7 @@ fi playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.standalone-worker.yml" --wait-for-control-center log "Create table" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -49,7 +49,7 @@ docker exec -d connect bash -c 'connect-standalone /tmp/worker.properties /tmp/c log "Sleeping 60 seconds to let the standalone connector doing the work" sleep 60 -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source.sh b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source.sh index 27ee4e8289..ce54b222b4 100755 --- a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source.sh +++ b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source.sh @@ -37,7 +37,7 @@ playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker- log "Create table" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -92,7 +92,7 @@ EOF sleep 5 -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-jdbc-sap-hana-sink/docker-compose.plaintext.yml b/connect/connect-jdbc-sap-hana-sink/docker-compose.plaintext.yml index 7de15c955a..b253ad72eb 100644 --- a/connect/connect-jdbc-sap-hana-sink/docker-compose.plaintext.yml +++ b/connect/connect-jdbc-sap-hana-sink/docker-compose.plaintext.yml @@ -3,7 +3,7 @@ services: sap: # https://github.com/mpern/hana-docker - image: "saplabs/hanaexpress:2.00.072.00.20231123.1" + image: "saplabs/hanaexpress:2.00.076.00.20240701.1" restart: "unless-stopped" hostname: sap container_name: sap diff --git a/connect/connect-jdbc-sap-hana-source/docker-compose.plaintext.yml b/connect/connect-jdbc-sap-hana-source/docker-compose.plaintext.yml index 8f8c4f54bc..ca104172bd 100644 --- a/connect/connect-jdbc-sap-hana-source/docker-compose.plaintext.yml +++ b/connect/connect-jdbc-sap-hana-source/docker-compose.plaintext.yml @@ -3,7 +3,7 @@ services: sap: # https://github.com/mpern/hana-docker - image: "saplabs/hanaexpress:2.00.072.00.20231123.1" + image: "saplabs/hanaexpress:2.00.076.00.20240701.1" restart: "unless-stopped" hostname: sap container_name: sap diff --git a/connect/connect-jdbc-sqlserver-sink/README.md b/connect/connect-jdbc-sqlserver-sink/README.md index bfeeb9d5f0..e2aeaf253c 100644 --- a/connect/connect-jdbc-sqlserver-sink/README.md +++ b/connect/connect-jdbc-sqlserver-sink/README.md @@ -163,7 +163,7 @@ EOF Show content of `orders` table: ```bash -$ ocker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +$ ocker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF select * from orders GO EOF diff --git a/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh b/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh index 4037723924..3d03e3c1ca 100755 --- a/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh +++ b/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh @@ -131,7 +131,7 @@ EOF sleep 5 log "Show content of orders table:" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF select * from orders GO EOF diff --git a/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink.sh b/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink.sh index 696849db5b..74d5c0fd74 100755 --- a/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink.sh +++ b/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink.sh @@ -74,7 +74,7 @@ EOF sleep 5 log "Show content of orders table:" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF select * from orders GO EOF diff --git a/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh b/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh index f5146424dc..e1b5346f47 100755 --- a/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh +++ b/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh @@ -134,7 +134,7 @@ EOF sleep 5 log "Show content of orders table:" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF select * from orders GO EOF diff --git a/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink.sh b/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink.sh index a1a6e3d889..8fdfb488a1 100755 --- a/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink.sh +++ b/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink.sh @@ -86,7 +86,7 @@ EOF sleep 5 log "Show content of orders table:" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! > /tmp/result.log 2>&1 <<-EOF select * from orders GO EOF diff --git a/connect/connect-jdbc-sqlserver-source/README.md b/connect/connect-jdbc-sqlserver-source/README.md index dc2823b4f3..d163d87d2a 100644 --- a/connect/connect-jdbc-sqlserver-source/README.md +++ b/connect/connect-jdbc-sqlserver-source/README.md @@ -32,7 +32,7 @@ $ just use command and search for sqlserver-microsoft-ssl.sh in Load inventory.sql to SQL Server ```bash -$ cat ../../connect/connect-jdbc-sqlserver-source/inventory.sql | docker exec -i sqlserver bash -c '/opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password!' +$ cat ../../connect/connect-jdbc-sqlserver-source/inventory.sql | docker exec -i sqlserver bash -c '/opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password!' ``` ### JTDS JDBC driver @@ -171,7 +171,7 @@ $ curl -X PUT \ Insert one more row: ```bash -$ docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +$ docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh b/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh index cb777c7ca4..c8fdd95ea8 100755 --- a/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh +++ b/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh @@ -65,7 +65,7 @@ PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.jtds-ssl.yml" log "Create table" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -110,7 +110,7 @@ EOF sleep 5 -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-jdbc-sqlserver-source/sqlserver-jtds.sh b/connect/connect-jdbc-sqlserver-source/sqlserver-jtds.sh index 6865cb6d5a..647cf948de 100755 --- a/connect/connect-jdbc-sqlserver-source/sqlserver-jtds.sh +++ b/connect/connect-jdbc-sqlserver-source/sqlserver-jtds.sh @@ -30,7 +30,7 @@ PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.jtds.yml" log "Create table" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -75,7 +75,7 @@ EOF sleep 5 -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh b/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh index 0ade2f6206..531ea308f0 100755 --- a/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh +++ b/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh @@ -67,7 +67,7 @@ PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.microsoft-ssl.yml" log "Create table" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -113,7 +113,7 @@ EOF sleep 5 -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft.sh b/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft.sh index 2392ccbabf..b2e1ce7876 100755 --- a/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft.sh +++ b/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft.sh @@ -40,7 +40,7 @@ PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.microsoft.yml" log "Create table" -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF -- Create the test database CREATE DATABASE testDB; GO @@ -85,7 +85,7 @@ EOF sleep 5 -docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -No -U sa -P Password! << EOF +docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF USE testDB; INSERT INTO customers(first_name,last_name,email) VALUES ('Pam','Thomas','pam@office.com'); GO diff --git a/connect/connect-sap-hana-sink/docker-compose.plaintext.yml b/connect/connect-sap-hana-sink/docker-compose.plaintext.yml index f94de7c703..b842947868 100644 --- a/connect/connect-sap-hana-sink/docker-compose.plaintext.yml +++ b/connect/connect-sap-hana-sink/docker-compose.plaintext.yml @@ -3,7 +3,7 @@ services: sap: # https://github.com/mpern/hana-docker - image: "saplabs/hanaexpress:2.00.072.00.20231123.1" + image: "saplabs/hanaexpress:2.00.076.00.20240701.1" restart: "unless-stopped" hostname: sap container_name: sap From fd36b1b4b99f74d2d35c97984cea0c3915b517c5 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 11 Sep 2024 15:51:04 +0200 Subject: [PATCH 016/659] wip (#5) * update * bump to 3.24.4 * fix for jdk17 * fix schema * cleanup pushtopic * Add HTTP Sink V2 Fully Managed example #5885 --- .github/workflows/ci.yml | 2 +- ccloud/fm-http-v2-sink/README.md | 21 + .../docker-compose.basic-auth.yml | 32 + .../docker-compose.mtls-auth.yml | 32 + .../fm-http-v2-sink/docker-compose.noauth.yml | 31 + .../fm-http-v2-sink/docker-compose.oauth2.yml | 31 + .../fully-managed-http-v2-basic-auth.sh | 104 +++ .../fully-managed-http-v2-sink-mtls-auth.sh | 128 +++ .../fully-managed-http-v2-sink-oauth2.sh | 121 +++ .../fully-managed-http-v2-sink.sh | 105 +++ ccloud/fm-http-v2-sink/ngrok-basic-auth.yml | 5 + ccloud/fm-http-v2-sink/ngrok-mtls-auth.yml | 5 + ccloud/fm-http-v2-sink/ngrok.yml | 5 + ccloud/fm-http-v2-sink/stop.sh | 10 + .../docker-compose.plaintext.ha-kerberos.yml | 2 + .../docker-compose.plaintext.ha-kerberos.yml | 2 + .../docker-compose.plaintext.yml | 3 +- .../connect-jdbc-vertica-sink/vertica-sink.sh | 3 +- docs/content-template.md | 1 + .../producer/pom.xml | 2 +- other/schema-format-protobuf/producer/pom.xml | 2 +- scripts/cli/completions.bash | 884 +++++++++--------- scripts/cli/confluent-hub-plugin-list.txt | 1 + scripts/cli/confluent-kafka-region-list.txt | 2 +- scripts/cli/playground | 538 ++++++----- .../src/commands/cleanup-cloud-resources.sh | 12 + 26 files changed, 1391 insertions(+), 693 deletions(-) create mode 100644 ccloud/fm-http-v2-sink/README.md create mode 100644 ccloud/fm-http-v2-sink/docker-compose.basic-auth.yml create mode 100644 ccloud/fm-http-v2-sink/docker-compose.mtls-auth.yml create mode 100644 ccloud/fm-http-v2-sink/docker-compose.noauth.yml create mode 100644 ccloud/fm-http-v2-sink/docker-compose.oauth2.yml create mode 100755 ccloud/fm-http-v2-sink/fully-managed-http-v2-basic-auth.sh create mode 100755 ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-mtls-auth.sh create mode 100755 ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-oauth2.sh create mode 100755 ccloud/fm-http-v2-sink/fully-managed-http-v2-sink.sh create mode 100644 ccloud/fm-http-v2-sink/ngrok-basic-auth.yml create mode 100644 ccloud/fm-http-v2-sink/ngrok-mtls-auth.yml create mode 100644 ccloud/fm-http-v2-sink/ngrok.yml create mode 100755 ccloud/fm-http-v2-sink/stop.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2edda96d82..72b4725006 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -139,7 +139,7 @@ jobs: "🚀 connect/connect-jdbc-sap-hana-sink connect/connect-jdbc-sap-hana-source connect/connect-sap-hana-sink", # requiring ngrok - "🚀2️⃣ ccloud/fm-influxdb2-sink ccloud/fm-influxdb2-source ccloud/fm-jdbc-oracle19-source ccloud/fm-jdbc-oracle19-sink ccloud/fm-cdc-oracle19-source ccloud/fm-rabbitmq-source ccloud/fm-zendesk-source ccloud/fm-splunk-sink ccloud/fm-rabbitmq-sink ccloud/fm-jdbc-mysql-sink ccloud/fm-sftp-source ccloud/fm-http-sink ccloud/fm-http-source", + "🚀2️⃣ ccloud/fm-influxdb2-sink ccloud/fm-influxdb2-source ccloud/fm-jdbc-oracle19-source ccloud/fm-jdbc-oracle19-sink ccloud/fm-cdc-oracle19-source ccloud/fm-rabbitmq-source ccloud/fm-zendesk-source ccloud/fm-splunk-sink ccloud/fm-rabbitmq-sink ccloud/fm-jdbc-mysql-sink ccloud/fm-sftp-source ccloud/fm-http-sink ccloud/fm-http-v2-sink ccloud/fm-http-source", "🚀3️⃣ ccloud/fm-cdc-oracle11-source ccloud/fm-solace-sink ccloud/fm-opensearch-sink ccloud/fm-sftp-sink ccloud/fm-redis-sink" ] steps: diff --git a/ccloud/fm-http-v2-sink/README.md b/ccloud/fm-http-v2-sink/README.md new file mode 100644 index 0000000000..8f97668a37 --- /dev/null +++ b/ccloud/fm-http-v2-sink/README.md @@ -0,0 +1,21 @@ +# Fully Managed HTTP Sink V2 connector + + + +## Objective + +Quickly test [Fully Managed HTTP V2 Sink](https://docs.confluent.io/cloud/current/connectors/cc-http-sink-v2.html) connector. + + +## Prerequisites + +See [here](https://kafka-docker-playground.io/#/how-to-use?id=%f0%9f%8c%a4%ef%b8%8f-confluent-cloud-examples) + +## How to run + +Simply run: + +``` +$ just use command and search for fully-managed-http-sink.sh in this folder +``` + diff --git a/ccloud/fm-http-v2-sink/docker-compose.basic-auth.yml b/ccloud/fm-http-v2-sink/docker-compose.basic-auth.yml new file mode 100644 index 0000000000..2c6ed3f668 --- /dev/null +++ b/ccloud/fm-http-v2-sink/docker-compose.basic-auth.yml @@ -0,0 +1,32 @@ +--- +services: + + httpserver: + image: vdesabou/http-sink-demo + hostname: httpserver + container_name: httpserver + ports: + - "9083:8080" + environment: + SPRING_PROFILES_ACTIVE: 'basic-auth' + + # https://ngrok.com/docs/using-ngrok-with/docker/ + ngrok: + image: ngrok/ngrok:latest + hostname: ngrok + container_name: ngrok + ports: + - 4040:4040 + restart: unless-stopped + links: + - httpserver + command: + - "start" + - "--all" + - "--log=stdout" + - "--config" + - "/etc/ngrok.yml" + volumes: + - ../../ccloud/fm-http-sink/ngrok-basic-auth.yml:/etc/ngrok.yml + environment: + NGROK_AUTHTOKEN: $NGROK_AUTH_TOKEN \ No newline at end of file diff --git a/ccloud/fm-http-v2-sink/docker-compose.mtls-auth.yml b/ccloud/fm-http-v2-sink/docker-compose.mtls-auth.yml new file mode 100644 index 0000000000..b3c7b2af13 --- /dev/null +++ b/ccloud/fm-http-v2-sink/docker-compose.mtls-auth.yml @@ -0,0 +1,32 @@ +--- +services: + + httpserver: + image: vdesabou/http-sink-demo + hostname: httpserver + container_name: httpserver + ports: + - "8643:8443" + environment: + SPRING_PROFILES_ACTIVE: 'ssl-auth' + + # https://ngrok.com/docs/using-ngrok-with/docker/ + ngrok: + image: ngrok/ngrok:latest + hostname: ngrok + container_name: ngrok + ports: + - 4040:4040 + restart: unless-stopped + links: + - httpserver + command: + - "start" + - "--all" + - "--log=stdout" + - "--config" + - "/etc/ngrok.yml" + volumes: + - ../../ccloud/fm-http-sink/ngrok-mtls-auth.yml:/etc/ngrok.yml + environment: + NGROK_AUTHTOKEN: $NGROK_AUTH_TOKEN \ No newline at end of file diff --git a/ccloud/fm-http-v2-sink/docker-compose.noauth.yml b/ccloud/fm-http-v2-sink/docker-compose.noauth.yml new file mode 100644 index 0000000000..e0b48fd152 --- /dev/null +++ b/ccloud/fm-http-v2-sink/docker-compose.noauth.yml @@ -0,0 +1,31 @@ +--- +services: + + httpserver: + build: + context: ../../connect/connect-http-sink/httpserver + hostname: httpserver + container_name: httpserver + ports: + - "9006:9006" + + # https://ngrok.com/docs/using-ngrok-with/docker/ + ngrok: + image: ngrok/ngrok:latest + hostname: ngrok + container_name: ngrok + ports: + - 4040:4040 + restart: unless-stopped + links: + - httpserver + command: + - "start" + - "--all" + - "--log=stdout" + - "--config" + - "/etc/ngrok.yml" + volumes: + - ../../ccloud/fm-http-sink/ngrok.yml:/etc/ngrok.yml + environment: + NGROK_AUTHTOKEN: $NGROK_AUTH_TOKEN \ No newline at end of file diff --git a/ccloud/fm-http-v2-sink/docker-compose.oauth2.yml b/ccloud/fm-http-v2-sink/docker-compose.oauth2.yml new file mode 100644 index 0000000000..31a2602fc5 --- /dev/null +++ b/ccloud/fm-http-v2-sink/docker-compose.oauth2.yml @@ -0,0 +1,31 @@ +--- +services: + + httpserver: + build: + context: ../../connect/connect-http-sink/httpserver-oauth2 + hostname: httpserver + container_name: httpserver + ports: + - "9006:9006" + + # https://ngrok.com/docs/using-ngrok-with/docker/ + ngrok: + image: ngrok/ngrok:latest + hostname: ngrok + container_name: ngrok + ports: + - 4040:4040 + restart: unless-stopped + links: + - httpserver + command: + - "start" + - "--all" + - "--log=stdout" + - "--config" + - "/etc/ngrok.yml" + volumes: + - ../../ccloud/fm-http-sink/ngrok.yml:/etc/ngrok.yml + environment: + NGROK_AUTHTOKEN: $NGROK_AUTH_TOKEN \ No newline at end of file diff --git a/ccloud/fm-http-v2-sink/fully-managed-http-v2-basic-auth.sh b/ccloud/fm-http-v2-sink/fully-managed-http-v2-basic-auth.sh new file mode 100755 index 0000000000..6019b5116a --- /dev/null +++ b/ccloud/fm-http-v2-sink/fully-managed-http-v2-basic-auth.sh @@ -0,0 +1,104 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +NGROK_AUTH_TOKEN=${NGROK_AUTH_TOKEN:-$1} + +display_ngrok_warning + +bootstrap_ccloud_environment + +docker compose -f docker-compose.basic-auth.yml build +docker compose -f docker-compose.basic-auth.yml down -v --remove-orphans +docker compose -f docker-compose.basic-auth.yml up -d --quiet-pull + +sleep 5 + +log "Waiting for ngrok to start" +while true +do + container_id=$(docker ps -q -f name=ngrok) + if [ -n "$container_id" ] + then + status=$(docker inspect --format '{{.State.Status}}' $container_id) + if [ "$status" = "running" ] + then + log "Getting ngrok hostname and port" + NGROK_URL=$(curl --silent http://127.0.0.1:4040/api/tunnels | jq -r '.tunnels[0].public_url') + NGROK_HOSTNAME=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 1) + NGROK_PORT=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 2) + + if ! [[ $NGROK_PORT =~ ^[0-9]+$ ]] + then + log "NGROK_PORT is not a valid number, keep retrying..." + continue + else + break + fi + fi + fi + log "Waiting for container ngrok to start..." + sleep 5 +done + +log "Creating http-topic topic in Confluent Cloud" +set +e +playground topic create --topic http-topic +set -e + +log "Sending messages to topic http-topic" +playground topic produce -t http-topic --nb-messages 10 --forced-value '{"f1":"value%g"}' << 'EOF' +{ + "type": "record", + "name": "myrecord", + "fields": [ + { + "name": "f1", + "type": "string" + } + ] +} +EOF + +connector_name="HttpSinkV2_$USER" +set +e +playground connector delete --connector $connector_name > /dev/null 2>&1 +set -e + +log "Creating fully managed connector" +playground connector create-or-update --connector $connector_name << EOF +{ + "connector.class": "HttpSinkV2", + "name": "$connector_name", + "kafka.auth.mode": "KAFKA_API_KEY", + "kafka.api.key": "$CLOUD_KEY", + "kafka.api.secret": "$CLOUD_SECRET", + "topics": "http-topic", + "input.data.format": "AVRO", + "http.api.base.url": "http://$NGROK_HOSTNAME:$NGROK_PORT", + "behavior.on.error": "FAIL", + "apis.num": "1", + "api1.http.api.path": "/api/messages", + "api1.topics": "http-topic", + "api1.request.body.format" : "JSON", + "api1.http.request.headers": "Content-Type: application/json", + "api1.test.api": "false", + "tasks.max" : "1", + "auth.type": "BASIC", + "connection.user": "admin", + "connection.password": "password" +} +EOF +wait_for_ccloud_connector_up $connector_name 180 + +connectorId=$(get_ccloud_connector_lcc $connector_name) + +log "Verifying topic success-$connectorId" +playground topic consume --topic success-$connectorId --min-expected-messages 10 --timeout 60 + +log "Do you want to delete the fully managed connector $connector_name ?" +check_if_continue + +playground connector delete --connector $connector_name \ No newline at end of file diff --git a/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-mtls-auth.sh b/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-mtls-auth.sh new file mode 100755 index 0000000000..5714d30a01 --- /dev/null +++ b/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-mtls-auth.sh @@ -0,0 +1,128 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +NGROK_AUTH_TOKEN=${NGROK_AUTH_TOKEN:-$1} + +display_ngrok_warning + +bootstrap_ccloud_environment + + + +docker compose -f docker-compose.mtls-auth.yml build +docker compose -f docker-compose.mtls-auth.yml down -v --remove-orphans +docker compose -f docker-compose.mtls-auth.yml up -d --quiet-pull + +sleep 5 + +log "Waiting for ngrok to start" +while true +do + container_id=$(docker ps -q -f name=ngrok) + if [ -n "$container_id" ] + then + status=$(docker inspect --format '{{.State.Status}}' $container_id) + if [ "$status" = "running" ] + then + log "Getting ngrok hostname and port" + NGROK_URL=$(curl --silent http://127.0.0.1:4040/api/tunnels | jq -r '.tunnels[0].public_url') + NGROK_HOSTNAME=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 1) + NGROK_PORT=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 2) + + if ! [[ $NGROK_PORT =~ ^[0-9]+$ ]] + then + log "NGROK_PORT is not a valid number, keep retrying..." + continue + else + break + fi + fi + fi + log "Waiting for container ngrok to start..." + sleep 5 +done + +log "Creating http-topic topic in Confluent Cloud" +set +e +playground topic create --topic http-topic +set -e + +log "Sending messages to topic http-topic" +playground topic produce -t http-topic --nb-messages 10 --forced-value '{"f1":"value%g"}' << 'EOF' +{ + "type": "record", + "name": "myrecord", + "fields": [ + { + "name": "f1", + "type": "string" + } + ] +} +EOF + +connector_name="HttpSinkV2_$USER" +set +e +playground connector delete --connector $connector_name > /dev/null 2>&1 +set -e + +cd ../../connect/connect-http-sink/ +base64_truststore=$(cat $PWD/security/truststore.http-service-mtls-auth.jks | base64 | tr -d '\n') +base64_keystore=$(cat $PWD/security/keystore.http-service-mtls-auth.jks | base64 | tr -d '\n') +cd - + +log "Creating fully managed connector" +playground connector create-or-update --connector $connector_name << EOF +{ + "connector.class": "HttpSinkV2", + "name": "$connector_name", + "kafka.auth.mode": "KAFKA_API_KEY", + "kafka.api.key": "$CLOUD_KEY", + "kafka.api.secret": "$CLOUD_SECRET", + "topics": "http-topic", + "input.data.format": "AVRO", + "http.api.base.url": "https://$NGROK_HOSTNAME:$NGROK_PORT", + "behavior.on.error": "FAIL", + "apis.num": "1", + "api1.http.api.path": "/api/messages", + "api1.topics": "http-topic", + "api1.request.body.format" : "JSON", + "api1.http.request.headers": "Content-Type: application/json", + "api1.test.api": "false", + "tasks.max" : "1", + + "https.ssl.enabled": "true", + "https.ssl.truststorefile": "data:text/plain;base64,$base64_truststore", + "https.ssl.truststore.password": "confluent", + "https.ssl.keystorefile": "data:text/plain;base64,$base64_keystore", + "https.ssl.keystore.password": "confluent", + "https.ssl.key.password": "confluent", + "https.ssl.protocol": "TLSv1.2", + "https.host.verifier.enabled": "false" +} +EOF +wait_for_ccloud_connector_up $connector_name 180 + + +connectorId=$(get_ccloud_connector_lcc $connector_name) + +log "Verifying topic success-$connectorId" +playground topic consume --topic success-$connectorId --min-expected-messages 10 --timeout 60 + +sleep 10 + +log "Confirm that the data was sent to the HTTP endpoint." +cd ../../connect/connect-http-sink/ +curl --cert ./security/http-service-mtls-auth.certificate.pem --key ./security/http-service-mtls-auth.key --tlsv1.2 --cacert ./security/snakeoil-ca-1.crt -X GET https://localhost:8643/api/messages | jq . > /tmp/result.log 2>&1 +cd - +cat /tmp/result.log +grep "10" /tmp/result.log + + +log "Do you want to delete the fully managed connector $connector_name ?" +check_if_continue + +playground connector delete --connector $connector_name \ No newline at end of file diff --git a/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-oauth2.sh b/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-oauth2.sh new file mode 100755 index 0000000000..169896ac53 --- /dev/null +++ b/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-oauth2.sh @@ -0,0 +1,121 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +NGROK_AUTH_TOKEN=${NGROK_AUTH_TOKEN:-$1} + +display_ngrok_warning + +bootstrap_ccloud_environment + + + +docker compose -f docker-compose.oauth2.yml build +docker compose -f docker-compose.oauth2.yml down -v --remove-orphans +docker compose -f docker-compose.oauth2.yml up -d --quiet-pull + +sleep 5 + +log "Waiting for ngrok to start" +while true +do + container_id=$(docker ps -q -f name=ngrok) + if [ -n "$container_id" ] + then + status=$(docker inspect --format '{{.State.Status}}' $container_id) + if [ "$status" = "running" ] + then + log "Getting ngrok hostname and port" + NGROK_URL=$(curl --silent http://127.0.0.1:4040/api/tunnels | jq -r '.tunnels[0].public_url') + NGROK_HOSTNAME=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 1) + NGROK_PORT=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 2) + + if ! [[ $NGROK_PORT =~ ^[0-9]+$ ]] + then + log "NGROK_PORT is not a valid number, keep retrying..." + continue + else + break + fi + fi + fi + log "Waiting for container ngrok to start..." + sleep 5 +done + +log "Creating http-topic topic in Confluent Cloud" +set +e +playground topic create --topic http-topic +set -e + +log "Sending messages to topic http-topic" +playground topic produce -t http-topic --nb-messages 10 --forced-value '{"f1":"value%g"}' << 'EOF' +{ + "type": "record", + "name": "myrecord", + "fields": [ + { + "name": "f1", + "type": "string" + } + ] +} +EOF + +connector_name="HttpSinkV2_$USER" +set +e +playground connector delete --connector $connector_name > /dev/null 2>&1 +set -e + +log "Set webserver to reply with 200" +curl -X PUT -H "Content-Type: application/json" --data '{"errorCode": 200}' http://localhost:9006/set-response-error-code +# curl -X PUT -H "Content-Type: application/json" --data '{"delay": 2000}' http://localhost:9006/set-response-time +# curl -X PUT -H "Content-Type: application/json" --data '{"message":"Hello, World!"}' http://localhost:9006/set-response-body + +log "Creating fully managed connector" +playground connector create-or-update --connector $connector_name << EOF +{ + "connector.class": "HttpSinkV2", + "name": "$connector_name", + "kafka.auth.mode": "KAFKA_API_KEY", + "kafka.api.key": "$CLOUD_KEY", + "kafka.api.secret": "$CLOUD_SECRET", + "topics": "http-topic", + "input.data.format": "AVRO", + "http.api.base.url": "http://$NGROK_HOSTNAME:$NGROK_PORT", + "behavior.on.error": "FAIL", + "apis.num": "1", + "api1.http.api.path": "/", + "api1.topics": "http-topic", + "api1.request.body.format" : "JSON", + "api1.http.request.headers": "Content-Type: application/json", + "api1.test.api": "false", + "tasks.max" : "1", + "auth.type": "OAUTH2", + "oauth2.token.url": "http://$NGROK_HOSTNAME:$NGROK_PORT/oauth/token", + "oauth2.client.id": "confidentialApplication", + "oauth2.client.secret": "topSecret", + "oauth2.token.property": "accessToken" +} +EOF +wait_for_ccloud_connector_up $connector_name 180 + +connectorId=$(get_ccloud_connector_lcc $connector_name) + +log "Verifying topic success-$connectorId" +playground topic consume --topic success-$connectorId --min-expected-messages 10 --timeout 60 + +log "Do you want to delete the fully managed connector $connector_name ?" +check_if_continue + +playground connector delete --connector $connector_name + + +# create token, see https://github.com/pedroetb/node-oauth2-server-example#with-client_credentials-grant-1 +# token=$(curl -X POST \ +# http://localhost:9006/oauth/token \ +# -H 'Content-Type: application/x-www-form-urlencoded' \ +# -H 'Authorization: Basic Y29uZmlkZW50aWFsQXBwbGljYXRpb246dG9wU2VjcmV0' \ +# -d 'grant_type=client_credentials&scope=any' | jq -r '.accessToken') \ No newline at end of file diff --git a/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink.sh b/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink.sh new file mode 100755 index 0000000000..683a4eff6e --- /dev/null +++ b/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink.sh @@ -0,0 +1,105 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +bootstrap_ccloud_environment + + + +docker compose -f docker-compose.noauth.yml build +docker compose -f docker-compose.noauth.yml down -v --remove-orphans +docker compose -f docker-compose.noauth.yml up -d --quiet-pull + +sleep 5 + +log "Waiting for ngrok to start" +while true +do + container_id=$(docker ps -q -f name=ngrok) + if [ -n "$container_id" ] + then + status=$(docker inspect --format '{{.State.Status}}' $container_id) + if [ "$status" = "running" ] + then + log "Getting ngrok hostname and port" + NGROK_URL=$(curl --silent http://127.0.0.1:4040/api/tunnels | jq -r '.tunnels[0].public_url') + NGROK_HOSTNAME=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 1) + NGROK_PORT=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 2) + + if ! [[ $NGROK_PORT =~ ^[0-9]+$ ]] + then + log "NGROK_PORT is not a valid number, keep retrying..." + continue + else + break + fi + fi + fi + log "Waiting for container ngrok to start..." + sleep 5 +done + +log "Creating http-topic topic in Confluent Cloud" +set +e +playground topic create --topic http-topic +set -e + +log "Sending messages to topic http-topic" +playground topic produce -t http-topic --nb-messages 10 --forced-value '{"f1":"value%g"}' << 'EOF' +{ + "type": "record", + "name": "myrecord", + "fields": [ + { + "name": "f1", + "type": "string" + } + ] +} +EOF + +connector_name="HttpSinkV2_$USER" +set +e +playground connector delete --connector $connector_name > /dev/null 2>&1 +set -e + +log "Set webserver to reply with 200" +curl -X PUT -H "Content-Type: application/json" --data '{"errorCode": 200}' http://localhost:9006/set-response-error-code +# curl -X PUT -H "Content-Type: application/json" --data '{"delay": 2000}' http://localhost:9006/set-response-time +# curl -X PUT -H "Content-Type: application/json" --data '{"message":"Hello, World!"}' http://localhost:9006/set-response-body + +log "Creating fully managed connector" +playground connector create-or-update --connector $connector_name << EOF +{ + "connector.class": "HttpSinkV2", + "name": "$connector_name", + "topics": "http-topic", + "kafka.auth.mode": "KAFKA_API_KEY", + "kafka.api.key": "$CLOUD_KEY", + "kafka.api.secret": "$CLOUD_SECRET", + "input.data.format": "AVRO", + "http.api.base.url": "http://$NGROK_HOSTNAME:$NGROK_PORT", + "behavior.on.error": "FAIL", + "apis.num": "1", + "api1.http.api.path": "/", + "api1.topics": "http-topic", + "api1.request.body.format" : "JSON", + "api1.http.request.headers": "Content-Type: application/json", + "api1.test.api": "false", + "tasks.max" : "1" +} +EOF +wait_for_ccloud_connector_up $connector_name 180 + + +connectorId=$(get_ccloud_connector_lcc $connector_name) + +log "Verifying topic success-$connectorId" +playground topic consume --topic success-$connectorId --min-expected-messages 10 --timeout 60 + +log "Do you want to delete the fully managed connector $connector_name ?" +check_if_continue + +playground connector delete --connector $connector_name diff --git a/ccloud/fm-http-v2-sink/ngrok-basic-auth.yml b/ccloud/fm-http-v2-sink/ngrok-basic-auth.yml new file mode 100644 index 0000000000..a2893217cd --- /dev/null +++ b/ccloud/fm-http-v2-sink/ngrok-basic-auth.yml @@ -0,0 +1,5 @@ +version: 2 +tunnels: + httpserver: + addr: httpserver:8080 + proto: tcp \ No newline at end of file diff --git a/ccloud/fm-http-v2-sink/ngrok-mtls-auth.yml b/ccloud/fm-http-v2-sink/ngrok-mtls-auth.yml new file mode 100644 index 0000000000..98fbe6a388 --- /dev/null +++ b/ccloud/fm-http-v2-sink/ngrok-mtls-auth.yml @@ -0,0 +1,5 @@ +version: 2 +tunnels: + httpserver: + addr: httpserver:8443 + proto: tcp \ No newline at end of file diff --git a/ccloud/fm-http-v2-sink/ngrok.yml b/ccloud/fm-http-v2-sink/ngrok.yml new file mode 100644 index 0000000000..1a1e7ce0a1 --- /dev/null +++ b/ccloud/fm-http-v2-sink/ngrok.yml @@ -0,0 +1,5 @@ +version: 2 +tunnels: + httpserver: + addr: httpserver:9006 + proto: tcp \ No newline at end of file diff --git a/ccloud/fm-http-v2-sink/stop.sh b/ccloud/fm-http-v2-sink/stop.sh new file mode 100755 index 0000000000..1ff863e145 --- /dev/null +++ b/ccloud/fm-http-v2-sink/stop.sh @@ -0,0 +1,10 @@ +#!/bin/bash + + + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +docker compose -f docker-compose.oauth2.yml down -v --remove-orphans + +maybe_delete_ccloud_environment \ No newline at end of file diff --git a/connect/connect-hdfs2-sink/docker-compose.plaintext.ha-kerberos.yml b/connect/connect-hdfs2-sink/docker-compose.plaintext.ha-kerberos.yml index 6a8bb28032..c81bc0b816 100644 --- a/connect/connect-hdfs2-sink/docker-compose.plaintext.ha-kerberos.yml +++ b/connect/connect-hdfs2-sink/docker-compose.plaintext.ha-kerberos.yml @@ -150,6 +150,8 @@ services: - ../../connect/connect-hdfs2-sink/ha-kerberos/hdfs-site.xml:/opt/hadoop/etc/hadoop/hdfs-site.xml environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-hdfs + # JDK 17 + KAFKA_OPTS: --add-opens=java.security.jgss/sun.security.krb5=ALL-UNNAMED networks: default: diff --git a/connect/connect-hdfs3-sink/docker-compose.plaintext.ha-kerberos.yml b/connect/connect-hdfs3-sink/docker-compose.plaintext.ha-kerberos.yml index 8b0346ebb0..d0b4989267 100644 --- a/connect/connect-hdfs3-sink/docker-compose.plaintext.ha-kerberos.yml +++ b/connect/connect-hdfs3-sink/docker-compose.plaintext.ha-kerberos.yml @@ -132,6 +132,8 @@ services: - ../../connect/connect-hdfs3-sink/ha-kerberos/hdfs-site.xml:/opt/hadoop/etc/hadoop/hdfs-site.xml environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-hdfs3 + # JDK 17 + KAFKA_OPTS: --add-opens=java.security.jgss/sun.security.krb5=ALL-UNNAMED networks: default: diff --git a/connect/connect-jdbc-vertica-sink/docker-compose.plaintext.yml b/connect/connect-jdbc-vertica-sink/docker-compose.plaintext.yml index a6f24ec635..80b000a10b 100644 --- a/connect/connect-jdbc-vertica-sink/docker-compose.plaintext.yml +++ b/connect/connect-jdbc-vertica-sink/docker-compose.plaintext.yml @@ -2,7 +2,8 @@ services: vertica: - image: jbfavre/vertica:latest + image: cjonesy/docker-vertica + #image: cjonesy/docker-vertica # in order to use vertica db 10, build your own docker image as described here https://github.com/cjonesy/docker-vertica hostname: vertica container_name: vertica ports: diff --git a/connect/connect-jdbc-vertica-sink/vertica-sink.sh b/connect/connect-jdbc-vertica-sink/vertica-sink.sh index 31c7600336..035029d787 100755 --- a/connect/connect-jdbc-vertica-sink/vertica-sink.sh +++ b/connect/connect-jdbc-vertica-sink/vertica-sink.sh @@ -23,7 +23,8 @@ log "VERTICA has started!" log "Create the table and insert data." docker exec -i vertica /opt/vertica/bin/vsql -hlocalhost -Udbadmin << EOF -create table mytable(f1 varchar(20)); +CREATE SCHEMA docker.docker; +create table docker.mytable(f1 varchar(20)); EOF sleep 2 diff --git a/docs/content-template.md b/docs/content-template.md index cda93b1c6a..081a3f28ab 100644 --- a/docs/content-template.md +++ b/docs/content-template.md @@ -224,6 +224,7 @@ - [Google Cloud Storage Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-gcp-gcs-source) :ccloud/fm-gcp-gcs-source: - [Google Cloud Pub/Sub Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-gcp-pubsub-source) :ccloud/fm-gcp-pubsub-source: - [HTTP Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-http-sink) :ccloud/fm-http-sink: + - [HTTP V2 Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-http-v2-sink) :ccloud/fm-http-v2-sink: - [HTTP Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-http-source) :ccloud/fm-http-source: - [IBM MQ Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-ibm-mq-source) :ccloud/fm-ibm-mq-source: - [InfluxDB 2 Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-influxdb2-source) :ccloud/fm-influxdb2-source: diff --git a/other/schema-format-protobuf-with-key/producer/pom.xml b/other/schema-format-protobuf-with-key/producer/pom.xml index 7c5b5aa163..8dfce3d981 100644 --- a/other/schema-format-protobuf-with-key/producer/pom.xml +++ b/other/schema-format-protobuf-with-key/producer/pom.xml @@ -11,7 +11,7 @@ 1.8 UTF-8 UTF-8 - 3.16.3 + 3.24.4 3.11.4 6.2.0 2.8.0 diff --git a/other/schema-format-protobuf/producer/pom.xml b/other/schema-format-protobuf/producer/pom.xml index 7c5b5aa163..8dfce3d981 100644 --- a/other/schema-format-protobuf/producer/pom.xml +++ b/other/schema-format-protobuf/producer/pom.xml @@ -11,7 +11,7 @@ 1.8 UTF-8 UTF-8 - 3.16.3 + 3.24.4 3.11.4 6.2.0 2.8.0 diff --git a/scripts/cli/completions.bash b/scripts/cli/completions.bash index 3d26d236c2..97dc052cb7 100644 --- a/scripts/cli/completions.bash +++ b/scripts/cli/completions.bash @@ -64,32 +64,32 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'topic set-schema-compatibility'*'--compatibility') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") - ;; - *'connector-plugin search-jar'*'--connector-plugin') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; - *'connector open-ccloud-connector-in-browser'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'topic set-schema-compatibility'*'--compatibility') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") + ;; + + *'ec2 sync-repro-folder local-to-ec2'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; *'tcp-proxy toggle-reads-client'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'ec2 sync-repro-folder local-to-ec2'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'connector offsets get-offsets-request-status'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; *'ec2 sync-repro-folder ec2-to-local'*'--instance') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'connector offsets get-offsets-request-status'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'connector open-ccloud-connector-in-browser'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'connector show-config-parameters'*'--connector') @@ -100,14 +100,14 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; - *'topic produce'*'--value-subject-name-strategy') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") - ;; - *'connector open-ccloud-connector-in-browser'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--browser --connector --help -c -h")" -- "$cur") ;; + *'topic produce'*'--value-subject-name-strategy') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") + ;; + *'tcp-proxy close-all-connection-with-error'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -120,36 +120,36 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'debug enable-remote-debugging'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - *'topic produce'*'--key-subject-name-strategy') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") ;; - *'schema set-compatibility'*'--compatibility') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") + *'debug enable-remote-debugging'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'config open-ccloud-connector-in-browser'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h automatically browser")" -- "$cur") ;; + *'schema set-compatibility'*'--compatibility') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") + ;; + *'container set-environment-variables'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug generate-diagnostics'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector create-or-update'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'topic set-schema-compatibility'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector create-or-update'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug generate-diagnostics'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'ec2 sync-repro-folder ec2-to-local'*'-i') @@ -160,42 +160,50 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'tcp-proxy toggle-accept-connections'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'container get-properties'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'tcp-proxy toggle-accept-connections'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + *'container set-environment-variables'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --env --help --restore-original-values -c -h")" -- "$cur") ;; - *'ec2 sync-repro-folder local-to-ec2'*) + *'ec2 sync-repro-folder ec2-to-local'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'ec2 sync-repro-folder ec2-to-local'*) + *'ec2 sync-repro-folder local-to-ec2'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'connector select-config'*'--connector') + *'connector offsets reset'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector show-config-parameters'*'-c') + *'connector offsets alter'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector offsets alter'*'--connector') + *'connector show-config-parameters'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector offsets reset'*'--connector') + *'connector select-config'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; + *'cleanup-cloud-resources'*'--resource') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure ccloud salesforce")" -- "$cur") + ;; + + *'schema set-compatibility'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + ;; + *'schema get-compatibility'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; @@ -204,36 +212,36 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'schema set-compatibility'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'connector show-config-parameters'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-refresh --help --only-show-json --open --verbose -c -h -o -v")" -- "$cur") ;; - *'cleanup-cloud-resources'*'--resource') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure ccloud salesforce")" -- "$cur") + *'connector show-config'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug flight-recorder'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector offsets get'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'topic produce'*'--compression-codec') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "gzip snappy lz4 zstd")" -- "$cur") ;; - *'connector show-config-parameters'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-refresh --help --only-show-json --open --verbose -c -h -o -v")" -- "$cur") + *'debug flight-recorder'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'topic set-schema-compatibility'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector offsets get'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container change-jdk'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector show-config'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'tcp-proxy toggle-writes-service'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; *'topic get-number-records'*'--topic') @@ -244,60 +252,52 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy toggle-writes-service'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'tools install-vscode-extension'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'container change-jdk'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'tcp-proxy break'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'topic set-schema-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --topic --verbose -h -t -v")" -- "$cur") + *'tcp-proxy toggle-reads-service'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'tools install-vscode-extension'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'tcp-proxy delay'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; *'debug block-traffic'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector log-level'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'tcp-proxy toggle-reads-service'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'topic produce'*'--validate-config') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") ;; *'topic display-consumer-offsets'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --verbose -h -v")" -- "$cur") ;; - *'tcp-proxy break'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") - ;; - *'tcp-proxy toggle-writes-client'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'topic produce'*'--validate-config') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") + *'topic set-schema-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --topic --verbose -h -t -v")" -- "$cur") ;; - *'tcp-proxy delay'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + *'connector log-level'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'tcp-proxy toggle-reads-client'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'connector snippets'*'--converter') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "avro protobuf json-schema json json-schema-enabled string bytearray")" -- "$cur") + *'debug flight-recorder'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") ;; *'tools read-parquet-file'*'--file') @@ -308,40 +308,40 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "8 11 17 21 22")" -- "$cur") ;; - *'update-version'*'--connector-jar') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") + *'debug enable-remote-debugging'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'update-version'*'--connector-zip') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") + *'connector show-lag'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'connector-plugin search-jar'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; - *'debug flight-recorder'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") + *'update-version'*'--connector-jar') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") ;; - *'debug enable-remote-debugging'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'update-version'*'--connector-zip') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") ;; - *'connector show-lag'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'connector snippets'*'--converter') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "avro protobuf json-schema json json-schema-enabled string bytearray")" -- "$cur") ;; - *'connector create-or-update'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'debug generate-diagnostics'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic produce'*'--compatibility') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") + *'topic consume'*'--value-subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'debug thread-dump'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic produce'*'--compatibility') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; *'connector unpause'*'--connector') @@ -352,16 +352,16 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector restart'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug thread-dump'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic consume'*'--value-subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'connector restart'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug generate-diagnostics'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector create-or-update'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; *'container unpause'*'--container') @@ -372,32 +372,32 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'connector-plugin versions'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") + ;; + *'connector status'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container resume'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector-plugin search-jar'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--class --connector-plugin --connector-tag --help -c -h")" -- "$cur") ;; - *'connector resume'*'--connector') + *'connector delete'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector-plugin versions'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") - ;; - - *'connector-plugin search-jar'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--class --connector-plugin --connector-tag --help -c -h")" -- "$cur") + *'connector resume'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'debug block-traffic'*'--action') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") ;; - *'connector delete'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container resume'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'connector update'*'--connector') @@ -408,48 +408,44 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector pause'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container get-ip-addresses'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector log-level'*'--level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'container get-properties'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug log-level set'*'--level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'debug generate-diagnostics'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'container pause'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic consume'*'--key-subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'connector create-or-update'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level --offsets --package --skip-automatic-connector-config --validate --verbose --wait-for-zero-lag -c -h -l -p -v")" -- "$cur") + *'topic get-number-records'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'container get-properties'*'-c') + *'get-jmx-metrics'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container get-ip-addresses'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - - *'debug heap-dump'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector log-level'*'--level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'get-jmx-metrics'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'debug log-level set'*'--level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'topic get-number-records'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'connector create-or-update'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level --offsets --package --skip-automatic-connector-config --validate --verbose --wait-for-zero-lag -c -h -l -p -v")" -- "$cur") ;; - *'debug generate-diagnostics'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'connector pause'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'tools read-avro-file'*'--file') @@ -460,160 +456,172 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'topic consume'*'--key-subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'debug heap-dump'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tools read-parquet-file'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") + *'container pause'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'container logs'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector stop'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug tcp-dump'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy start'*'--hostname') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'ec2 create'*'--instance-type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "c1.medium c1.xlarge c3.2xlarge c3.4xlarge c3.8xlarge c3.large c3.xlarge c4.2xlarge c4.4xlarge c4.large c4.xlarge m1.large m1.medium m1.small m1.xlarge m2.2xlarge m2.4xlarge m2.xlarge m3.2xlarge m3.large m3.medium m3.xlarge m4.10xlarge m4.2xlarge m4.4xlarge m4.large m4.xlarge t1.micro t2.large t2.medium t2.micro t2.nano t2.small t3.2xlarge")" -- "$cur") ;; - *'container kill'*'--container') + *'container exec'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy get-connections'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'debug block-traffic'*'--port') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'repro bootstrap'*'--pipeline') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro --sink-only "$cur")")" -- "$cur") + *'container kill'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'repro bootstrap'*'--producer') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") + *'connector select-config'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug tcp-dump'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'tcp-proxy get-connections'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; *'connector-plugin versions'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-plugin --force-refresh --help --last -c -h")" -- "$cur") ;; - *'connector offsets alter'*'-c') + *'tools read-parquet-file'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") + ;; + + *'connector offsets reset'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container exec'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'repro bootstrap'*'--pipeline') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro --sink-only "$cur")")" -- "$cur") ;; - *'connector select-config'*'-c') + *'connector stop'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector offsets reset'*'-c') + *'connector offsets alter'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'ec2 create'*'--instance-type') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "c1.medium c1.xlarge c3.2xlarge c3.4xlarge c3.8xlarge c3.large c3.xlarge c4.2xlarge c4.4xlarge c4.large c4.xlarge m1.large m1.medium m1.small m1.xlarge m2.2xlarge m2.4xlarge m2.xlarge m3.2xlarge m3.large m3.medium m3.xlarge m4.10xlarge m4.2xlarge m4.4xlarge m4.large m4.xlarge t1.micro t2.large t2.medium t2.micro t2.nano t2.small t3.2xlarge")" -- "$cur") + *'repro bootstrap'*'--producer') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") ;; - *'debug block-traffic'*'--port') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") + *'tcp-proxy start'*'--hostname') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'schema set-mode'*'--subject') + *'schema register'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'schema set-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --subject --verbose -h -v")" -- "$cur") + *'topic produce'*'--reference') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; *'schema get-compatibility'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; - *'schema register'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'config folder_zip_or_jar'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'schema get-mode'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'container get-properties'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'container ssh'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'schema set-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --subject --verbose -h -v")" -- "$cur") ;; - *'remove-all-docker-images'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'container ssh'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'run'*'--cluster-environment') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-environment-list "$cur")")" -- "$cur") + *'schema set-mode'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'container get-properties'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'schema get-mode'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'topic produce'*'--reference') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + *'debug java-debug'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "enable disable")" -- "$cur") ;; - *'config folder_zip_or_jar'*) + *'remove-all-docker-images'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'debug java-debug'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "enable disable")" -- "$cur") - ;; - *'topic get-number-records'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") ;; - *'tools read-parquet-file'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + *'run'*'--cluster-environment') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-environment-list "$cur")")" -- "$cur") ;; - *'debug flight-recorder'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector offsets get'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'connector offsets reset'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; *'schema register'*'--schema') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'cleanup-cloud-resources'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--force --help --resource -h")" -- "$cur") + *'debug flight-recorder'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector offsets reset'*) + *'connector offsets alter'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'connector select-config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") + *'cleanup-cloud-resources'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--force --help --resource -h")" -- "$cur") ;; - *'connector offsets get'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'tools read-parquet-file'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; *'connector show-config'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector offsets alter'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'connector select-config'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") + ;; + + *'container change-jdk'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + + *'debug java-debug'*'--type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ssl_all ssl_handshake class_loading kerberos")" -- "$cur") ;; *'tools read-avro-file'*'-f') @@ -624,79 +632,67 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'debug java-debug'*'--type') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ssl_all ssl_handshake class_loading kerberos")" -- "$cur") + *'debug flight-recorder'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help -c -h")" -- "$cur") ;; - *'container change-jdk'*'-c') + *'debug block-traffic'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy start'*'--port') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") - ;; - - *'schema set-mode'*'--mode') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") - ;; - - *'repro bootstrap'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") + *'topic describe'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector log-level'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container exec'*'--shell') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'connector show-config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-rest-endpoint --help --verbose -c -h -v")" -- "$cur") + *'debug log-level set'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'topic describe'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'connector log-level'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'cleanup-cloud-details'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'tcp-proxy start'*'--port') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'ec2 sync-repro-folder'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h ec2-to-local local-to-ec2")" -- "$cur") + *'connector log-level'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector log-level'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'schema set-mode'*'--mode') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") ;; - *'debug log-level set'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'connector offsets get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'debug flight-recorder'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help -c -h")" -- "$cur") + *'connector show-config'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-rest-endpoint --help --verbose -c -h -v")" -- "$cur") ;; - *'debug block-traffic'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'repro bootstrap'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") ;; - *'container exec'*'--shell') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") + *'cleanup-cloud-details'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector offsets get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'ec2 sync-repro-folder'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h ec2-to-local local-to-ec2")" -- "$cur") ;; *'tools read-avro-file'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'ec2 delete'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") - ;; - - *'topic consume'*'--topic') + *'topic produce'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; @@ -704,7 +700,7 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'topic produce'*'--topic') + *'topic consume'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; @@ -716,35 +712,23 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container change-jdk'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --version -c -h")" -- "$cur") + *'ec2 delete'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") ;; *'container ssh'*'--shell') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'container restart'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'topic delete'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") - ;; - - *'debug log-level set'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --level --package -h -l -p")" -- "$cur") - ;; - - *'debug log-level get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --package -h -p")" -- "$cur") + *'container change-jdk'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --version -c -h")" -- "$cur") ;; - *'debug block-traffic'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --destination --help --port -c -h")" -- "$cur") + *'connector open-docs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") ;; - *'container unpause'*'-c') + *'container restart'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -752,43 +736,51 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector unpause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'schema get'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'connector restart'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'update-version'*'--tag') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") ;; - *'schema get'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'connector log-level'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level -c -h -l")" -- "$cur") ;; - *'connector open-docs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") + *'debug block-traffic'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --destination --help --port -c -h")" -- "$cur") ;; *'ec2 start'*'--instance') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'update-version'*'--tag') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") + *'debug log-level get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --package -h -p")" -- "$cur") + ;; + + *'debug log-level set'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --level --package -h -l -p")" -- "$cur") ;; *'run'*'--cluster-region') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-kafka-region-list "$cur")")" -- "$cur") ;; - *'connector log-level'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level -c -h -l")" -- "$cur") + *'topic delete'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'container resume'*'-c') + *'connector restart'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'container unpause'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector status'*'-c') + *'connector unpause'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -796,7 +788,19 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector delete'*'-c') + *'ec2 stop'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + ;; + + *'ec2 open'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + ;; + + *'connector snippets'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--converter --dlq --help -h")" -- "$cur") + ;; + + *'connector status'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -804,160 +808,152 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --ignore-current-versions -h")" -- "$cur") ;; - *'container kill-all'*) + *'get-docker-compose'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'debug java-debug'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'connector resume'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'repro import'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") ;; *'connector show-lag'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --interval --max-wait --verbose -c -h -v")" -- "$cur") ;; - *'get-docker-compose'*) + *'connector versions'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector snippets'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--converter --dlq --help -h")" -- "$cur") + *'connector delete'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'repro import'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") + *'container kill-all'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector update'*'-c') + *'connector resume'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'ec2 open'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") - ;; - - *'run'*'--connector-jar') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") + *'container resume'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'run'*'--cluster-cloud') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure")" -- "$cur") + *'topic produce'*'--key') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; *'run'*'--connector-zip') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") ;; - *'ec2 stop'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") - ;; - - *'connector versions'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'debug java-debug'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic produce'*'--key') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + *'connector update'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container pause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'run'*'--cluster-cloud') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure")" -- "$cur") ;; - *'container unpause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'run'*'--connector-jar') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") ;; - *'connector plugins'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help --verbose -h -v")" -- "$cur") + *'run'*'--cluster-name') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") ;; - *'container restart'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'debug heap-dump'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'connector offsets'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter get get-offsets-request-status reset")" -- "$cur") ;; - *'get-jmx-metrics'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'repro bootstrap'*'-p') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") ;; - *'debug heap-dump'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'repro bootstrap'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") ;; - *'debug thread-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'connector plugins'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help --verbose -h -v")" -- "$cur") ;; *'connector pause'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector unpause'*) + *'connector restart'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'repro bootstrap'*'-p') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") - ;; - - *'repro bootstrap'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") - ;; - - *'run'*'--cluster-type') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "basic standard dedicated")" -- "$cur") + *'container pause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'run'*'--cluster-name') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") + *'container unpause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'connector restart'*) + *'connector unpause'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'container resume'*) + *'container restart'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'container kill'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'get-jmx-metrics'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + + *'run'*'--cluster-type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "basic standard dedicated")" -- "$cur") ;; - *'container exec'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'debug thread-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; *'container logs'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'debug java-debug'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help --type -c -h")" -- "$cur") + ;; + *'connector-plugin'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h search-jar versions")" -- "$cur") ;; - *'connector resume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'container resume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'debug java-debug'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help --type -c -h")" -- "$cur") + *'topic describe'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + ;; + + *'connector delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; *'debug tcp-dump'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector status'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'config clipboard'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'connector update'*) @@ -968,83 +964,103 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; + *'connector resume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + ;; + *'run'*'--environment') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") ;; - *'config clipboard'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'container kill'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector delete'*) + *'connector status'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'topic describe'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") - ;; - - *'container pause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'container exec'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'container ssh'*'-s') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'container ssh'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'tcp-proxy break'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") ;; *'get-jmx-metrics'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --domain --help --open -c -d -h -o")" -- "$cur") ;; - *'debug heap-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") - ;; - *'debug log-level'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h get set")" -- "$cur") ;; - *'tcp-proxy break'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") + *'topic produce'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + ;; + + *'tcp-proxy start'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --delay-service-response --help --hostname --port --service-response-corrupt --skip-automatic-connector-config --throttle-service-response -h")" -- "$cur") ;; *'tcp-proxy delay'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") ;; - *'tcp-proxy start'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --delay-service-response --help --hostname --port --service-response-corrupt --skip-automatic-connector-config --throttle-service-response -h")" -- "$cur") + *'connector pause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + ;; + + *'repro bootstrap'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--custom-smt --description --file --help --pipeline -d -f -h")" -- "$cur") + ;; + + *'topic consume'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + ;; + + *'container pause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; *'schema register'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --schema --subject --verbose -h -v")" -- "$cur") ;; - *'schema get-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") + *'container ssh'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'repro bootstrap'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--custom-smt --description --file --help --pipeline -d -f -h")" -- "$cur") + *'debug heap-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") + ;; + + *'schema get-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; *'schema set-mode'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") ;; - *'topic produce'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'connector logs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") ;; - *'topic consume'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'update-version'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-jar --connector-tag --connector-zip --help --tag -h")" -- "$cur") ;; - *'connector pause'*) + *'topic describe'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") + ;; + + *'connector stop'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; @@ -1056,48 +1072,40 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") ;; - *'debug tcp-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --duration --help --port -c -h")" -- "$cur") + *'topic delete'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'repro import'*'-f') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") ;; - *'update-version'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-jar --connector-tag --connector-zip --help --tag -h")" -- "$cur") - ;; - *'container kill'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'connector stop'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") - ;; - - *'topic delete'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'debug tcp-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --duration --help --port -c -h")" -- "$cur") ;; - *'connector logs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") + *'topic produce'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") ;; - *'topic describe'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") + *'topic alter'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'container ssh'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") + *'schema delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --permanent --subject --verbose --version -h -v")" -- "$cur") ;; *'debug testssl'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'schema delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --permanent --subject --verbose --version -h -v")" -- "$cur") + *'topic consume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--grep --help --key-subject --max-characters --max-messages --min-expected-messages --plot-latencies-timestamp-field --tail --timeout --topic --value-subject --verbose -h -t -v")" -- "$cur") ;; *'switch-ccloud'*) @@ -1108,34 +1116,22 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'--output-level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") - ;; - - *'topic consume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--grep --help --key-subject --max-characters --max-messages --min-expected-messages --plot-latencies-timestamp-field --tail --timeout --topic --value-subject --verbose -h -t -v")" -- "$cur") - ;; - - *'topic produce'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") + *'container ssh'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") ;; - *'topic alter'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'--output-level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") ;; - *'repro export'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help -h")" -- "$cur") + *'ec2 delete'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") ;; *'repro import'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'ec2 delete'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") - ;; - *'topic delete'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --skip-delete-schema --topic --verbose -h -t -v")" -- "$cur") ;; @@ -1144,88 +1140,100 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --nb-partitions --topic --verbose -h -t -v")" -- "$cur") ;; - *'ec2 start'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'repro export'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help -h")" -- "$cur") ;; *'switch-back'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; + *'ec2 start'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + ;; + *'topic alter'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") ;; - *'ec2 delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + *'topic list'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'schema get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") + *'ec2 stop'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'ec2 open'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'ec2 create'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance-type --size --suffix -h")" -- "$cur") ;; - *'topic list'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'schema get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") ;; - *'ec2 create'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance-type --size --suffix -h")" -- "$cur") + *'ec2 delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; *'open'*'--file') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") ;; - *'ec2 stop'*'-i') + *'ec2 open'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'connector'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create-or-update delete log-level logs offsets open-ccloud-connector-in-browser open-docs pause plugins restart resume select-config show-config show-config-parameters show-lag snippets status stop unpause update versions")" -- "$cur") - ;; - *'container'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h change-jdk exec get-ip-addresses get-properties kill kill-all logs pause recreate restart resume set-environment-variables ssh unpause")" -- "$cur") ;; + *'ec2 start'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + ;; + + *'run'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") + ;; + *'tcp-proxy'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h break close-all-connection-with-error close-connection delay get-connections start toggle-accept-connections toggle-reads-client toggle-reads-service toggle-writes-client toggle-writes-service")" -- "$cur") ;; - *'open-docs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") + *'connector'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create-or-update delete log-level logs offsets open-ccloud-connector-in-browser open-docs pause plugins restart resume select-config show-config show-config-parameters show-lag snippets status stop unpause update versions")" -- "$cur") ;; - *'ec2 start'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + *'open-docs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") ;; - *'run'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") + *'run'*'--tag') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") ;; *'ec2 open'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--disable-sync-repro-folder --help --instance -h -i")" -- "$cur") ;; + *'ec2 list'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + *'ec2 stop'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'run'*'--tag') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") + *'history'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'ec2 list'*) + *'re-run'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'history'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'config'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h clipboard editor folder_zip_or_jar open-ccloud-connector-in-browser")" -- "$cur") ;; *'schema'*) @@ -1236,22 +1244,18 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") ;; - *'config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h clipboard editor folder_zip_or_jar open-ccloud-connector-in-browser")" -- "$cur") - ;; - *'status'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'re-run'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'topic'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter consume create delete describe display-consumer-offsets get-number-records list produce set-schema-compatibility")" -- "$cur") ;; + *'run'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") + ;; + *'debug'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h block-traffic enable-remote-debugging flight-recorder generate-diagnostics heap-dump java-debug log-level tcp-dump testssl thread-dump")" -- "$cur") ;; @@ -1264,30 +1268,26 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h bootstrap export import")" -- "$cur") ;; - *'run'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") + *'open'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; *'stop'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'open'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") - ;; - *'help'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'run'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--cluster-cloud --cluster-creds --cluster-environment --cluster-name --cluster-region --cluster-schema-registry-creds --cluster-type --connector-jar --connector-tag --connector-zip --enable-conduktor --enable-control-center --enable-jmx-grafana --enable-kcat --enable-ksqldb --enable-multiple-brokers --enable-multiple-connect-workers --enable-rest-proxy --enable-sql-datagen --environment --file --help --open --tag -f -h -o")" -- "$cur") - ;; - *'ec2'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create delete list open start stop sync-repro-folder")" -- "$cur") ;; + *'run'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--cluster-cloud --cluster-creds --cluster-environment --cluster-name --cluster-region --cluster-schema-registry-creds --cluster-type --connector-jar --connector-tag --connector-zip --enable-conduktor --enable-control-center --enable-jmx-grafana --enable-kcat --enable-ksqldb --enable-multiple-brokers --enable-multiple-connect-workers --enable-rest-proxy --enable-sql-datagen --environment --file --help --open --tag -f -h -o")" -- "$cur") + ;; + *'-o') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") ;; diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index 822e3bb3dc..1f1ea71301 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -152,6 +152,7 @@ kategmbh/kafka-adapter-for-sap-process-orchestration kinetica/kinetica-connector konghq/kong-kafka-upstream-plugin levyx/xenon-connector +lightstreamer/kafka-connect-lightstreamer llofberg/kafka-connect-aws-lambda marklogic/kafka-marklogic-connector markteehan/file-chunk-sink diff --git a/scripts/cli/confluent-kafka-region-list.txt b/scripts/cli/confluent-kafka-region-list.txt index d9f55330d5..dc40f725ed 100644 --- a/scripts/cli/confluent-kafka-region-list.txt +++ b/scripts/cli/confluent-kafka-region-list.txt @@ -62,6 +62,7 @@ Paris(francecentral)/francecentral Phoenix(westus3)/westus3 Pune(centralindia)/centralindia S.Carolina(us-east1)/us-east1 +SaltLakeCity(us-west3)/us-west3 Santiago(southamerica-west1)/southamerica-west1 SaoPaulo(southamerica-east1)/southamerica-east1 SaoPaulostate(brazilsouth)/brazilsouth @@ -72,7 +73,6 @@ Singapore(ap-southeast-1)/ap-southeast-1 Singapore(asia-southeast1)/asia-southeast1 Singapore(southeastasia)/southeastasia Spain(eu-south-2)/eu-south-2 -Spain(spaincentral)/spaincentral Stockholm(eu-north-1)/eu-north-1 Sydney(ap-southeast-2)/ap-southeast-2 Sydney(australia-southeast1)/australia-southeast1 diff --git a/scripts/cli/playground b/scripts/cli/playground index ce7ab946e8..da51e1959a 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# This script was generated by bashly 1.2.0 (https://bashly.dannyb.co) +# This script was generated by bashly 1.2.2 (https://bashly.dannyb.co) # Modifying it manually is not recommended # :wrapper.bash3_bouncer @@ -171,7 +171,7 @@ playground_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "Global Options:")" # :command.usage_flags @@ -183,7 +183,7 @@ playground_usage() { # :flag.usage printf " %s\n" "$(magenta "--output-level, -o LEVEL")" printf " ❕Log level used by all commands\n \n Default is INFO (all INFO, WARN and ERROR will be printed in command output)\n" - printf " Allowed: INFO, WARN, ERROR\n" + printf " %s\n" "Allowed: INFO, WARN, ERROR" echo # :command.usage_fixed_flags @@ -207,7 +207,7 @@ playground_help_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -236,7 +236,7 @@ playground_status_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -257,7 +257,7 @@ playground_get_docker_ports_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -278,7 +278,7 @@ playground_get_connector_list_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -299,7 +299,7 @@ playground_get_ec2_instance_list_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -328,7 +328,7 @@ playground_get_ec2_cloudformation_list_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -357,7 +357,7 @@ playground_get_zazkia_connection_list_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -378,7 +378,7 @@ playground_generate_fzf_find_files_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -399,7 +399,7 @@ playground_generate_tag_list_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -420,7 +420,7 @@ playground_generate_connector_plugin_list_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -441,7 +441,7 @@ playground_generate_kafka_region_list_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -462,7 +462,7 @@ playground_get_connector_plugin_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -491,7 +491,7 @@ playground_get_ccloud_environment_list_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -520,7 +520,7 @@ playground_get_ccloud_cluster_list_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -549,7 +549,7 @@ playground_get_tag_list_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -578,7 +578,7 @@ playground_get_kafka_region_list_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -607,7 +607,7 @@ playground_get_topic_list_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -634,7 +634,7 @@ playground_get_subject_list_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -661,7 +661,7 @@ playground_get_examples_list_with_fzf_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -751,14 +751,14 @@ playground_get_zip_or_jar_with_fzf_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--type TYPE")" printf "\n" - printf " Allowed: zip, jar\n" + printf " %s\n" "Allowed: zip, jar" echo # :command.usage_fixed_flags @@ -787,7 +787,7 @@ playground_get_specific_file_extension_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -822,7 +822,7 @@ playground_get_any_file_with_fzf_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -851,7 +851,7 @@ playground_get_playground_repro_export_with_fzf_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -880,7 +880,7 @@ playground_get_predefined_schemas_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -909,7 +909,7 @@ playground_update_readme_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -949,7 +949,7 @@ playground_bashly_reload_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -969,9 +969,11 @@ playground_state_usage() { printf " playground state [COMMAND] --help | -h\n" echo # :command.usage_commands + printf "%s\n" "$(bold "== Commands ==")" + echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -992,7 +994,7 @@ playground_state_show_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1013,7 +1015,7 @@ playground_state_get_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1048,7 +1050,7 @@ playground_state_set_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1088,7 +1090,7 @@ playground_state_del_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1130,7 +1132,7 @@ playground_config_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1151,7 +1153,7 @@ playground_config_show_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1172,7 +1174,7 @@ playground_config_get_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1207,7 +1209,7 @@ playground_config_set_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1247,7 +1249,7 @@ playground_config_editor_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1287,7 +1289,7 @@ playground_config_folder_zip_or_jar_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1322,7 +1324,7 @@ playground_config_clipboard_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1336,7 +1338,7 @@ playground_config_clipboard_usage() { # :argument.usage printf " %s\n" "$(blue "ENABLED")" printf "\n" - printf " Default: true\n" + printf " %s\n" "Default: true" echo # :command.usage_examples @@ -1368,7 +1370,7 @@ playground_config_open_ccloud_connector_in_browser_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1389,7 +1391,7 @@ playground_config_open_ccloud_connector_in_browser_automatically_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1403,7 +1405,7 @@ playground_config_open_ccloud_connector_in_browser_automatically_usage() { # :argument.usage printf " %s\n" "$(blue "AUTOMATICALLY")" printf "\n" - printf " Default: true\n" + printf " %s\n" "Default: true" echo # :command.usage_examples @@ -1425,7 +1427,7 @@ playground_config_open_ccloud_connector_in_browser_browser_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1439,7 +1441,7 @@ playground_config_open_ccloud_connector_in_browser_browser_usage() { # :argument.usage printf " %s\n" "$(blue "BROWSER")" printf "\n" - printf " Default: \n" + printf " %s\n" "Default: " echo # :command.usage_examples @@ -1465,15 +1467,15 @@ playground_run_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--environment ENVIRONMENT")" printf " 🔐 The environment to start when running a connector example \n \n - plaintext\n - ccloud\n - 2way-ssl\n - kerberos\n - kraft-external-plaintext\n - kraft-plaintext\n - ldap-authorizer-sasl-plain\n - ldap-sasl-plain\n - rbac-sasl-plain\n - sasl-plain\n - sasl-scram\n - sasl-ssl\n - ssl_kerberos\n \n Default is plaintext.\n This is only supported when example is a connector example\n" - printf " Allowed: ccloud, plaintext, sasl-ssl, sasl-plain, 2way-ssl, sasl-scram, kraft-external-plaintext, kraft-plaintext, kerberos, ssl_kerberos, ldap-authorizer-sasl-plain, ldap-sasl-plain, rbac-sasl-plain\n" - printf " Default: plaintext\n" + printf " %s\n" "Allowed: ccloud, plaintext, sasl-ssl, sasl-plain, 2way-ssl, sasl-scram, kraft-external-plaintext, kraft-plaintext, kerberos, ssl_kerberos, ldap-authorizer-sasl-plain, ldap-sasl-plain, rbac-sasl-plain" + printf " %s\n" "Default: plaintext" echo # :flag.usage @@ -1494,11 +1496,13 @@ playground_run_usage() { # :flag.usage printf " %s\n" "$(magenta "--connector-tag CONNECTOR_TAG")" printf " 🔗 Connector version to use\n \n By default, for each connector, the latest available version on Confluent\n Hub is used\n \n 🎓 Tip: set to \" \" in order to select the version dynamically\n" + printf " %s\n" "Conflicts: --connector-zip" echo # :flag.usage printf " %s\n" "$(magenta "--connector-zip CONNECTOR_ZIP")" printf " 🤐 Connector zip to use\n \n ❕ It must be absolute full path\n \n 🎓 Tip: use completion to trigger fzf completion \n use playground config folder_zip_or_jar ...\n (default is home folder and current folder is always included) to configure\n where to search the files\n" + printf " %s\n" "Conflicts: --connector-tag" echo # :flag.usage @@ -1554,13 +1558,13 @@ playground_run_usage() { # :flag.usage printf " %s\n" "$(magenta "--cluster-cloud CLUSTER-CLOUD")" printf " 🌤 The cloud provider: aws, gcp or azure. Default is aws\n \n 🎓 Tip: you can also use CLUSTER_CLOUD environment variable\n" - printf " Allowed: aws, gcp, azure\n" + printf " %s\n" "Allowed: aws, gcp, azure" echo # :flag.usage printf " %s\n" "$(magenta "--cluster-type CLUSTER-TYPE")" printf " 🔋 The cluster type: basic, standard or dedicated. Default is basic\n \n 🎓 Tip: you can also use CLUSTER_TYPE environment variable\n" - printf " Allowed: basic, standard, dedicated\n" + printf " %s\n" "Allowed: basic, standard, dedicated" echo # :flag.usage @@ -1611,7 +1615,7 @@ playground_re_run_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1637,7 +1641,7 @@ playground_history_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1663,15 +1667,15 @@ playground_start_environment_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--environment ENVIRONMENT")" printf " 🔐 The environment to start . \n \n - ccloud\n - 2way-ssl\n - kerberos\n - kraft-external-plaintext\n - kraft-plaintext\n - ldap-authorizer-sasl-plain\n - ldap-sasl-plain\n - mdc-kerberos\n - mdc-plaintext\n - mdc-sasl-plain\n - plaintext\n - rbac-sasl-plain\n - sasl-plain\n - sasl-scram\n - sasl-ssl\n - ssl_kerberos\n \n Default is plaintext\n" - printf " Allowed: ccloud, 2way-ssl, kerberos, kraft-external-plaintext, kraft-plaintext, ldap-authorizer-sasl-plain, ldap-sasl-plain, mdc-kerberos, mdc-plaintext, mdc-sasl-plain, plaintext, rbac-sasl-plain, sasl-plain, sasl-scram, sasl-ssl, ssl_kerberos\n" - printf " Default: plaintext\n" + printf " %s\n" "Allowed: ccloud, 2way-ssl, kerberos, kraft-external-plaintext, kraft-plaintext, ldap-authorizer-sasl-plain, ldap-sasl-plain, mdc-kerberos, mdc-plaintext, mdc-sasl-plain, plaintext, rbac-sasl-plain, sasl-plain, sasl-scram, sasl-ssl, ssl_kerberos" + printf " %s\n" "Default: plaintext" echo # :flag.usage @@ -1713,7 +1717,7 @@ playground_switch_ccloud_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1734,7 +1738,7 @@ playground_switch_back_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1755,7 +1759,7 @@ playground_update_version_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -1767,11 +1771,13 @@ playground_update_version_usage() { # :flag.usage printf " %s\n" "$(magenta "--connector-tag CONNECTOR_TAG")" printf " 🔗 Connector version to use\n \n By default, for each connector, the latest available version on Confluent\n Hub is used\n \n 🎓 Tip: set to \" \" in order to select the version dynamically\n" + printf " %s\n" "Conflicts: --connector-zip" echo # :flag.usage printf " %s\n" "$(magenta "--connector-zip CONNECTOR_ZIP")" printf " 🤐 Connector zip to use\n \n ❕ It must be absolute full path\n \n 🎓 Tip: use completion to trigger fzf completion \n use playground config folder_zip_or_jar ...\n (default is home folder and current folder is always included) to configure\n where to search the files\n" + printf " %s\n" "Conflicts: --connector-tag" echo # :flag.usage @@ -1808,7 +1814,7 @@ playground_open_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -1835,7 +1841,7 @@ playground_stop_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1856,7 +1862,7 @@ playground_remove_all_docker_images_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1882,7 +1888,7 @@ playground_cleanup_cloud_details_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -1903,7 +1909,7 @@ playground_open_docs_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -1935,7 +1941,7 @@ playground_cleanup_cloud_resources_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -1947,8 +1953,8 @@ playground_cleanup_cloud_resources_usage() { # :flag.usage printf " %s\n" "$(magenta "--resource RESOURCE (repeatable)")" printf " 🛁 resource to cleanup\n \n If not provided, all of them are cleaned up\n \n 🎓 Tip: you can pass multiple resources by specifying --resource multiple\n times\n" - printf " Allowed: aws, gcp, azure, ccloud, salesforce\n" - printf " Default: aws, gcp, azure, ccloud, salesforce\n" + printf " %s\n" "Allowed: aws, gcp, azure, ccloud, salesforce" + printf " %s\n" "Default: aws, gcp, azure, ccloud, salesforce" echo # :command.usage_fixed_flags @@ -2008,7 +2014,7 @@ playground_repro_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -2022,7 +2028,7 @@ playground_repro_usage() { # :environment_variable.usage printf " %s\n" "$(cyan "OUTPUT_FOLDER")" printf " 📁 Output folder where to generate bootstrapped files\n" - printf " Default: reproduction-models\n" + printf " %s\n" "Default: reproduction-models" echo fi @@ -2038,7 +2044,7 @@ playground_repro_export_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2065,7 +2071,7 @@ playground_repro_import_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2097,7 +2103,7 @@ playground_repro_bootstrap_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2119,6 +2125,7 @@ playground_repro_bootstrap_usage() { # :flag.usage printf " %s\n" "$(magenta "--pipeline SINK_FILE (repeatable)")" printf " 🔖 Sink example file to use for creating a pipeline. multiple --pipeline\n flags can be used to create a pipeline with multiple sinks.\n \n ❕ It must be absolute full path. \n \n 🎓 Tip: use completion to trigger fzf completion\n" + printf " %s\n" "Conflicts: --producer" echo # :command.usage_fixed_flags @@ -2144,7 +2151,7 @@ playground_get_docker_compose_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -2175,7 +2182,7 @@ playground_schema_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -2196,18 +2203,20 @@ playground_schema_get_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--subject SUBJECT")" printf " 📛 Subject name\n" + printf " %s\n" "Conflicts: id" echo # :flag.usage printf " %s\n" "$(magenta "--id ID")" printf " 💯 Schema id\n" + printf " %s\n" "Conflicts: subject, deleted" echo # :flag.usage @@ -2218,6 +2227,7 @@ playground_schema_get_usage() { # :flag.usage printf " %s\n" "$(magenta "--deleted")" printf " 🧟 Include soft deleted subjects\n" + printf " %s\n" "Conflicts: id" echo # :command.usage_fixed_flags @@ -2245,7 +2255,7 @@ playground_schema_register_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2262,7 +2272,7 @@ playground_schema_register_usage() { # :flag.usage printf " %s\n" "$(magenta "--schema SCHEMA")" printf " 🔥 You can either:\n \n * Set your own schema (avro, json-schema, protobuf) with stdin (see example\n section).\n \n * Use completion to select predefined schemas (or use your own schema file)\n 🎓 Tip: use completion to trigger fzf completion\n" - printf " Default: -\n" + printf " %s\n" "Default: -" echo # :flag.usage @@ -2293,7 +2303,7 @@ playground_schema_get_compatibility_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2325,7 +2335,7 @@ playground_schema_set_compatibility_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2342,7 +2352,7 @@ playground_schema_set_compatibility_usage() { # :flag.usage printf " %s\n" "$(magenta "--compatibility COMPATIBILITY (required)")" printf " Schema Registry compatibility rule\n" - printf " Allowed: BACKWARD, BACKWARD_TRANSITIVE, FORWARD, FORWARD_TRANSITIVE, FULL, FULL_TRANSITIVE, NONE\n" + printf " %s\n" "Allowed: BACKWARD, BACKWARD_TRANSITIVE, FORWARD, FORWARD_TRANSITIVE, FULL, FULL_TRANSITIVE, NONE" echo # :command.usage_fixed_flags @@ -2363,7 +2373,7 @@ playground_schema_get_mode_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2400,7 +2410,7 @@ playground_schema_set_mode_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2417,7 +2427,7 @@ playground_schema_set_mode_usage() { # :flag.usage printf " %s\n" "$(magenta "--mode MODE (required)")" printf " Schema Registry mode\n" - printf " Allowed: IMPORT, READONLY, READWRITE\n" + printf " %s\n" "Allowed: IMPORT, READONLY, READWRITE" echo # :command.usage_fixed_flags @@ -2438,7 +2448,7 @@ playground_schema_delete_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2450,11 +2460,13 @@ playground_schema_delete_usage() { # :flag.usage printf " %s\n" "$(magenta "--version VERSION")" printf " 🔢 Schema version of the provided subject to delete\n \n Can only be used when --subject is provided\n" + printf " %s\n" "Conflicts: --id" echo # :flag.usage printf " %s\n" "$(magenta "--id ID")" printf " 🫵 Schema id\n \n Can only be used when --subject is provided\n" + printf " %s\n" "Conflicts: --version" echo # :flag.usage @@ -2504,7 +2516,7 @@ playground_tcp_proxy_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -2525,7 +2537,7 @@ playground_tcp_proxy_start_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2542,19 +2554,19 @@ playground_tcp_proxy_start_usage() { # :flag.usage printf " %s\n" "$(magenta "--throttle-service-response THROTTLE-SERVICE-RESPONSE")" printf " 🐌 Throttle service response. This is bytes per second.\n" - printf " Default: 0\n" + printf " %s\n" "Default: 0" echo # :flag.usage printf " %s\n" "$(magenta "--delay-service-response DELAY-SERVICE-RESPONSE")" printf " ⏲️ Add milliseconds delay to service response. Default is 0 ms.\n" - printf " Default: 0\n" + printf " %s\n" "Default: 0" echo # :flag.usage printf " %s\n" "$(magenta "--break-service-response BREAK-SERVICE-RESPONSE")" printf " 💔 Percentage of broken connections. Default is 0%%.\n" - printf " Default: 0\n" + printf " %s\n" "Default: 0" echo # :flag.usage @@ -2590,7 +2602,7 @@ playground_tcp_proxy_get_connections_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2622,7 +2634,7 @@ playground_tcp_proxy_delay_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2659,7 +2671,7 @@ playground_tcp_proxy_break_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2691,7 +2703,7 @@ playground_tcp_proxy_close_connection_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2718,7 +2730,7 @@ playground_tcp_proxy_close_all_connection_with_error_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -2739,7 +2751,7 @@ playground_tcp_proxy_toggle_accept_connections_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -2765,7 +2777,7 @@ playground_tcp_proxy_toggle_reads_client_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2797,7 +2809,7 @@ playground_tcp_proxy_toggle_reads_service_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2829,7 +2841,7 @@ playground_tcp_proxy_toggle_writes_client_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2861,7 +2873,7 @@ playground_tcp_proxy_toggle_writes_service_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2894,7 +2906,7 @@ playground_tools_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -2920,7 +2932,7 @@ playground_tools_install_vscode_extension_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -2946,7 +2958,7 @@ playground_tools_read_avro_file_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -2973,7 +2985,7 @@ playground_tools_read_parquet_file_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -3013,7 +3025,7 @@ playground_debug_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -3039,14 +3051,14 @@ playground_debug_enable_remote_debugging_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :command.usage_fixed_flags @@ -3079,7 +3091,7 @@ playground_debug_testssl_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -3119,14 +3131,14 @@ playground_debug_generate_diagnostics_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :command.usage_fixed_flags @@ -3158,14 +3170,14 @@ playground_debug_thread_dump_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :command.usage_fixed_flags @@ -3197,14 +3209,14 @@ playground_debug_heap_dump_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :flag.usage @@ -3241,14 +3253,14 @@ playground_debug_tcp_dump_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :flag.usage @@ -3259,7 +3271,7 @@ playground_debug_tcp_dump_usage() { # :flag.usage printf " %s\n" "$(magenta "--duration DURATION")" printf " Duration of the dump (default is 30 seconds).\n" - printf " Default: 30\n" + printf " %s\n" "Default: 30" echo # :command.usage_fixed_flags @@ -3285,14 +3297,14 @@ playground_debug_block_traffic_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :flag.usage @@ -3308,7 +3320,7 @@ playground_debug_block_traffic_usage() { # :flag.usage printf " %s\n" "$(magenta "--action ACTION (required)")" printf " 🟢 start or stop\n" - printf " Allowed: start, stop\n" + printf " %s\n" "Allowed: start, stop" echo # :command.usage_fixed_flags @@ -3335,27 +3347,27 @@ playground_debug_java_debug_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :flag.usage printf " %s\n" "$(magenta "--type TYPE (required)")" printf " - ssl_all: Enable all SSL debugging, i.e -Djavax.net.debug=all\n - ssl_handshake: Enable SSL handshake debugging, i.e\n -Djavax.net.debug=ssl:handshake\n - class_loading: Enable class loading debugging, i.e -verbose:class\n - kerberos: Enable Kerberos debugging, i.e -Dsun.security.krb5.debug=true\n" - printf " Allowed: ssl_all, ssl_handshake, class_loading, kerberos\n" + printf " %s\n" "Allowed: ssl_all, ssl_handshake, class_loading, kerberos" echo # :flag.usage printf " %s\n" "$(magenta "--action ACTION")" printf " 🟢 enable or disable\n" - printf " Allowed: enable, disable\n" - printf " Default: enable\n" + printf " %s\n" "Allowed: enable, disable" + printf " %s\n" "Default: enable" echo # :command.usage_fixed_flags @@ -3387,20 +3399,20 @@ playground_debug_flight_recorder_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :flag.usage printf " %s\n" "$(magenta "--action ACTION (required)")" printf " 🟢 start or stop\n" - printf " Allowed: start, stop\n" + printf " %s\n" "Allowed: start, stop" echo # :command.usage_fixed_flags @@ -3432,7 +3444,7 @@ playground_debug_log_level_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -3461,7 +3473,7 @@ playground_debug_log_level_get_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -3488,7 +3500,7 @@ playground_debug_log_level_set_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -3500,7 +3512,7 @@ playground_debug_log_level_set_usage() { # :flag.usage printf " %s\n" "$(magenta "--level, -l LEVEL (required)")" printf " ❕Log level\n" - printf " Allowed: INFO, WARN, DEBUG, TRACE\n" + printf " %s\n" "Allowed: INFO, WARN, DEBUG, TRACE" echo # :command.usage_fixed_flags @@ -3526,14 +3538,14 @@ playground_get_jmx_metrics_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :flag.usage @@ -3589,7 +3601,7 @@ playground_container_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -3615,14 +3627,14 @@ playground_container_get_properties_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :command.usage_fixed_flags @@ -3655,7 +3667,7 @@ playground_container_recreate_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -3682,7 +3694,7 @@ playground_container_get_ip_addresses_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -3708,7 +3720,7 @@ playground_container_kill_all_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -3729,30 +3741,33 @@ playground_container_logs_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :flag.usage printf " %s\n" "$(magenta "--open, -o")" printf " 🔖 Save output to a file and open with text editor set with playground config\n editor (default is code)\n" + printf " %s\n" "Conflicts: --wait-for-log" echo # :flag.usage printf " %s\n" "$(magenta "--wait-for-log, -w LOG")" printf " 😴 Wait until log appears\n" + printf " %s\n" "Conflicts: --open" echo # :flag.usage printf " %s\n" "$(magenta "--max-wait, -m MAX_WAIT")" printf " ⏳ Max time in seconds to wait when using --wait-for-log (default 600s)\n" - printf " Default: 600\n" + printf " %s\n" "Default: 600" + printf " %s\n" "Conflicts: --open" echo # :command.usage_fixed_flags @@ -3780,21 +3795,21 @@ playground_container_ssh_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :flag.usage printf " %s\n" "$(magenta "--shell, -s SHELL")" printf " 💾 Shell to use (default is bash)\n" - printf " Allowed: bash, sh, ksh, zsh\n" - printf " Default: bash\n" + printf " %s\n" "Allowed: bash, sh, ksh, zsh" + printf " %s\n" "Default: bash" echo # :command.usage_fixed_flags @@ -3827,20 +3842,20 @@ playground_container_change_jdk_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :flag.usage printf " %s\n" "$(magenta "--version VERSION (required)")" printf " 🤎 JDK version to use\n" - printf " Allowed: 8, 11, 17, 21, 22\n" + printf " %s\n" "Allowed: 8, 11, 17, 21, 22" echo # :command.usage_fixed_flags @@ -3866,14 +3881,14 @@ playground_container_exec_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :flag.usage @@ -3889,8 +3904,8 @@ playground_container_exec_usage() { # :flag.usage printf " %s\n" "$(magenta "--shell SHELL")" printf " 💾 Shell to use (default is bash)\n" - printf " Allowed: bash, sh, ksh, zsh\n" - printf " Default: bash\n" + printf " %s\n" "Allowed: bash, sh, ksh, zsh" + printf " %s\n" "Default: bash" echo # :command.usage_fixed_flags @@ -3918,14 +3933,14 @@ playground_container_restart_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :command.usage_fixed_flags @@ -3946,14 +3961,14 @@ playground_container_pause_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :command.usage_fixed_flags @@ -3976,14 +3991,14 @@ playground_container_resume_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :command.usage_fixed_flags @@ -4004,14 +4019,14 @@ playground_container_kill_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :command.usage_fixed_flags @@ -4037,24 +4052,26 @@ playground_container_set_environment_variables_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--container, -c CONTAINER")" printf " 🐳 Container name\n" - printf " Default: connect\n" + printf " %s\n" "Default: connect" echo # :flag.usage printf " %s\n" "$(magenta "--env ENV (repeatable)")" printf " 📦 Environment variables to set\n \n 🎓 Tip: you can pass multiple environment variables by specifying --env\n multiple times\n" + printf " %s\n" "Conflicts: --restore-original-values" echo # :flag.usage printf " %s\n" "$(magenta "--restore-original-values")" printf " 🧽 Restore back original values before any changes was made\n" + printf " %s\n" "Conflicts: --env" echo # :command.usage_fixed_flags @@ -4088,7 +4105,7 @@ playground_topic_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -4109,7 +4126,7 @@ playground_topic_get_number_records_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -4142,7 +4159,7 @@ playground_topic_display_consumer_offsets_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -4169,7 +4186,7 @@ playground_topic_list_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -4190,7 +4207,7 @@ playground_topic_describe_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -4222,7 +4239,7 @@ playground_topic_set_schema_compatibility_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -4234,7 +4251,7 @@ playground_topic_set_schema_compatibility_usage() { # :flag.usage printf " %s\n" "$(magenta "--compatibility COMPATIBILITY (required)")" printf " Schema Registry compatibility rule\n" - printf " Allowed: BACKWARD, BACKWARD_TRANSITIVE, FORWARD, FORWARD_TRANSITIVE, FULL, FULL_TRANSITIVE, NONE\n" + printf " %s\n" "Allowed: BACKWARD, BACKWARD_TRANSITIVE, FORWARD, FORWARD_TRANSITIVE, FULL, FULL_TRANSITIVE, NONE" echo # :flag.usage @@ -4260,7 +4277,7 @@ playground_topic_consume_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -4277,30 +4294,31 @@ playground_topic_consume_usage() { # :flag.usage printf " %s\n" "$(magenta "--max-messages MAX-MESSAGES")" printf " Max number of messages to display (default is 100)\n" - printf " Default: 100\n" + printf " %s\n" "Default: 100" echo # :flag.usage printf " %s\n" "$(magenta "--min-expected-messages MIN-EXPECTED-MESSAGES")" printf " Minimum expected number of messages to be present in topic, returns an error\n if this is not the case\n \n Note: --topic should be specified in this case.\n" - printf " Default: 0\n" + printf " %s\n" "Default: 0" echo # :flag.usage printf " %s\n" "$(magenta "--grep GREP")" printf " Verify that topic content contains record which contains specified string\n" - printf " Default: \n" + printf " %s\n" "Default: " echo # :flag.usage printf " %s\n" "$(magenta "--timeout TIMEOUT")" printf " Max number of seconds to wait when --min-expected-messages is used.\n \n Default is 60 seconds\n" - printf " Default: 60\n" + printf " %s\n" "Default: 60" echo # :flag.usage printf " %s\n" "$(magenta "--tail")" printf " Tail on logs.\n" + printf " %s\n" "Conflicts: --min-expected-messages, --max-messages" echo # :flag.usage @@ -4321,7 +4339,7 @@ playground_topic_consume_usage() { # :flag.usage printf " %s\n" "$(magenta "--max-characters MAX-CHARACTERS")" printf " Max characters per message to display (default is 3000)\n" - printf " Default: 3000\n" + printf " %s\n" "Default: 3000" echo # :command.usage_fixed_flags @@ -4347,7 +4365,7 @@ playground_topic_produce_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -4359,7 +4377,7 @@ playground_topic_produce_usage() { # :flag.usage printf " %s\n" "$(magenta "--value VALUE")" printf " 🔥 You can either:\n \n * Set your own schema (avro, json-schema, protobuf) with stdin (see example\n section).\n \n * You can also generate json data using json or sql format using syntax from\n https://github.com/MaterializeInc/datagen\n \n * Use completion to select predefined schemas (or use your own schema file)\n 🎓 Tip: use completion to trigger fzf completion\n \n * Directly set payload (\"%%g\" can be used to generate a counter)\n" - printf " Default: -\n" + printf " %s\n" "Default: -" echo # :flag.usage @@ -4375,49 +4393,49 @@ playground_topic_produce_usage() { # :flag.usage printf " %s\n" "$(magenta "--nb-messages NB-MESSAGES")" printf " 💯 Number of messages to produce (default is 1)\n \n 🎓 - if > (default 300000), messages\n will be sent in batches of (default\n 300000) records\n - if you set it to -1, an infinite number of records will also be sent\n in batches\n" - printf " Default: 1\n" + printf " %s\n" "Default: 1" echo # :flag.usage printf " %s\n" "$(magenta "--max-nb-messages-per-batch MAX-NB-MESSAGES-PER-BATCH")" printf " 🔼 Max number of messages to send per batch when --nb-messages >\n --max-nb-messages-per-batch\n if --nb-messages is set to -1, this is the number of messages sent per\n batch\n default is 300000\n" - printf " Default: 300000\n" + printf " %s\n" "Default: 300000" echo # :flag.usage printf " %s\n" "$(magenta "--sleep-time-between-batch SLEEP-TIME-BETWEEN-BATCH")" printf " 💤 Sleep time in seconds between batches\n default is 0\n" - printf " Default: 0\n" + printf " %s\n" "Default: 0" echo # :flag.usage printf " %s\n" "$(magenta "--nb-partitions NB-PARTITIONS")" printf " 🔢 Number of partitions for the topic. (default is 1)\n \n ❌ Important: If topic is existing, it will be re-created before producing to\n topic.\n" - printf " Default: 1\n" + printf " %s\n" "Default: 1" echo # :flag.usage printf " %s\n" "$(magenta "--compression-codec COMPRESSION-CODEC")" printf " 🤐 The compression codec: either 'gzip', 'snappy', 'lz4', or 'zstd'\n If not set, there is no compression\n" - printf " Allowed: gzip, snappy, lz4, zstd\n" + printf " %s\n" "Allowed: gzip, snappy, lz4, zstd" echo # :flag.usage printf " %s\n" "$(magenta "--compatibility COMPATIBILITY")" printf " Schema Registry compatibility rule\n" - printf " Allowed: BACKWARD, BACKWARD_TRANSITIVE, FORWARD, FORWARD_TRANSITIVE, FULL, FULL_TRANSITIVE, NONE\n" + printf " %s\n" "Allowed: BACKWARD, BACKWARD_TRANSITIVE, FORWARD, FORWARD_TRANSITIVE, FULL, FULL_TRANSITIVE, NONE" echo # :flag.usage printf " %s\n" "$(magenta "--key-subject-name-strategy KEY-SUBJECT-NAME-STRATEGY")" printf " Key Subject Name Strategy\n" - printf " Allowed: TopicNameStrategy, RecordNameStrategy, TopicRecordNameStrategy\n" + printf " %s\n" "Allowed: TopicNameStrategy, RecordNameStrategy, TopicRecordNameStrategy" echo # :flag.usage printf " %s\n" "$(magenta "--value-subject-name-strategy VALUE-SUBJECT-NAME-STRATEGY")" printf " Value Subject Name Strategy\n" - printf " Allowed: TopicNameStrategy, RecordNameStrategy, TopicRecordNameStrategy\n" + printf " %s\n" "Allowed: TopicNameStrategy, RecordNameStrategy, TopicRecordNameStrategy" echo # :flag.usage @@ -4468,7 +4486,7 @@ playground_topic_produce_usage() { # :flag.usage printf " %s\n" "$(magenta "--validate-config VALIDATE-CONFIG (repeatable)")" printf " 🔩 Converter configuration parameters to use \n \n See docs:\n https://docs.confluent.io/platform/current/schema-registry/connect.html#using-kconnect-long-with-sr\n \n 🎓 Tip: you can pass multiple parameters by specifying --validate-config\n multiple times\n" - printf " Allowed: scrub.invalid.names=true, enhanced.avro.schema.support=true, connect.meta.data=false, object.additional.properties=false, use.optional.for.nonrequired=true, ignore.default.for.nullables=true, generalized.sum.type.support=true, enhanced.protobuf.schema.support=true, generate.index.for.unions=false, int.for.enums=true, optional.for.nullables=true, generate.struct.for.nulls=true, wrapper.for.nullables=true, wrapper.for.raw.primitives=false\n" + printf " %s\n" "Allowed: scrub.invalid.names=true, enhanced.avro.schema.support=true, connect.meta.data=false, object.additional.properties=false, use.optional.for.nonrequired=true, ignore.default.for.nullables=true, generalized.sum.type.support=true, enhanced.protobuf.schema.support=true, generate.index.for.unions=false, int.for.enums=true, optional.for.nullables=true, generate.struct.for.nulls=true, wrapper.for.nullables=true, wrapper.for.raw.primitives=false" echo # :flag.usage @@ -4479,7 +4497,7 @@ playground_topic_produce_usage() { # :flag.usage printf " %s\n" "$(magenta "--record-size RECORD-SIZE")" printf " 🏋️ Record size in bytes, eg. 1048576 for 1MB\n \n 📢 If size is > 1Mb, --producer-property max.request.size and topic\n max.message.bytes will be automatically set to support the record size.\n" - printf " Default: 0\n" + printf " %s\n" "Default: 0" echo # :command.usage_fixed_flags @@ -4505,7 +4523,7 @@ playground_topic_create_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -4522,7 +4540,7 @@ playground_topic_create_usage() { # :flag.usage printf " %s\n" "$(magenta "--nb-partitions NB-PARTITIONS")" printf " Number of partitions for the topic. (default is 1)\n" - printf " Default: 1\n" + printf " %s\n" "Default: 1" echo # :command.usage_fixed_flags @@ -4555,7 +4573,7 @@ playground_topic_delete_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -4592,7 +4610,7 @@ playground_topic_alter_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -4641,7 +4659,7 @@ playground_connector_plugin_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -4662,7 +4680,7 @@ playground_connector_plugin_search_jar_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -4674,6 +4692,7 @@ playground_connector_plugin_search_jar_usage() { # :flag.usage printf " %s\n" "$(magenta "--connector-tag CONNECTOR_TAG")" printf " 🔗 Connector version to use\n \n By default, for each connector, the latest available version on Confluent\n Hub is used\n \n 🎓 Tip: set to \" \" in order to select the version dynamically\n" + printf " %s\n" "Conflicts: --connector-zip" echo # :flag.usage @@ -4704,7 +4723,7 @@ playground_connector_plugin_versions_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -4721,6 +4740,7 @@ playground_connector_plugin_versions_usage() { # :flag.usage printf " %s\n" "$(magenta "--last LAST")" printf " 🆕 Number of last versions to show\n" + printf " %s\n" "Conflicts: --all" echo # :command.usage_fixed_flags @@ -4771,7 +4791,7 @@ playground_connector_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -4801,7 +4821,7 @@ playground_connector_status_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -4845,7 +4865,7 @@ playground_connector_offsets_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -4871,7 +4891,7 @@ playground_connector_offsets_get_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -4908,7 +4928,7 @@ playground_connector_offsets_reset_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -4945,7 +4965,7 @@ playground_connector_offsets_alter_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -4982,7 +5002,7 @@ playground_connector_offsets_get_offsets_request_status_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5014,7 +5034,7 @@ playground_connector_plugins_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5046,7 +5066,7 @@ playground_connector_pause_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5083,7 +5103,7 @@ playground_connector_versions_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -5104,7 +5124,7 @@ playground_connector_restart_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5136,7 +5156,7 @@ playground_connector_stop_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5170,7 +5190,7 @@ playground_connector_resume_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5202,7 +5222,7 @@ playground_connector_delete_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5239,7 +5259,7 @@ playground_connector_show_lag_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5256,13 +5276,13 @@ playground_connector_show_lag_usage() { # :flag.usage printf " %s\n" "$(magenta "--interval INTERVAL")" printf " Interval between lag checks (default is 20 seconds).\n" - printf " Default: 20\n" + printf " %s\n" "Default: 20" echo # :flag.usage printf " %s\n" "$(magenta "--max-wait MAX_WAIT")" printf " ⏳ Max time in seconds to wait for lag to become 0. If set to 0 (default), it\n will run until all lag becomes 0.\n" - printf " Default: 0\n" + printf " %s\n" "Default: 0" echo # :command.usage_fixed_flags @@ -5288,7 +5308,7 @@ playground_connector_show_config_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5325,7 +5345,7 @@ playground_connector_show_config_parameters_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5377,7 +5397,7 @@ playground_connector_select_config_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5404,14 +5424,14 @@ playground_connector_snippets_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--converter CONVERTER")" printf " 🔌 Converter\n" - printf " Allowed: avro, protobuf, json-schema, json, json-schema-enabled, string, bytearray\n" + printf " %s\n" "Allowed: avro, protobuf, json-schema, json, json-schema-enabled, string, bytearray" echo # :flag.usage @@ -5442,7 +5462,7 @@ playground_connector_open_docs_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5474,7 +5494,7 @@ playground_connector_log_level_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5486,7 +5506,7 @@ playground_connector_log_level_usage() { # :flag.usage printf " %s\n" "$(magenta "--level, -l LEVEL (required)")" printf " ❕Log level\n" - printf " Allowed: INFO, WARN, DEBUG, TRACE\n" + printf " %s\n" "Allowed: INFO, WARN, DEBUG, TRACE" echo # :command.usage_fixed_flags @@ -5512,24 +5532,27 @@ playground_connector_logs_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--open, -o")" printf " 🔖 Save output to a file and open with text editor set with playground config\n editor (default is code)\n" + printf " %s\n" "Conflicts: --wait-for-log" echo # :flag.usage printf " %s\n" "$(magenta "--wait-for-log, -w LOG")" printf " 😴 Wait until log appears\n" + printf " %s\n" "Conflicts: --open" echo # :flag.usage printf " %s\n" "$(magenta "--max-wait, -m MAX_WAIT")" printf " ⏳ Max time in seconds to wait when using --wait-for-log (default 600s)\n" - printf " Default: 600\n" + printf " %s\n" "Default: 600" + printf " %s\n" "Conflicts: --open" echo # :flag.usage @@ -5555,7 +5578,7 @@ playground_connector_open_ccloud_connector_in_browser_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5587,7 +5610,7 @@ playground_connector_create_or_update_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5604,7 +5627,7 @@ playground_connector_create_or_update_usage() { # :flag.usage printf " %s\n" "$(magenta "--level, -l LEVEL")" printf " ❕Log level\n \n ⚠️ Not available for ccloud connectors\n" - printf " Allowed: INFO, WARN, DEBUG, TRACE\n" + printf " %s\n" "Allowed: INFO, WARN, DEBUG, TRACE" echo # :flag.usage @@ -5643,7 +5666,7 @@ playground_connector_create_or_update_usage() { # :argument.usage printf " %s\n" "$(blue "JSON")" printf " json (reads from stdin if empty)\n" - printf " Default: -\n" + printf " %s\n" "Default: -" echo # :command.usage_examples @@ -5664,7 +5687,7 @@ playground_connector_update_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5711,7 +5734,7 @@ playground_ec2_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -5737,21 +5760,21 @@ playground_ec2_create_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags # :flag.usage printf " %s\n" "$(magenta "--instance-type INSTANCE-TYPE")" printf " 🧑‍💻 instance type. default is t3.2xlarge\n" - printf " Allowed: c1.medium, c1.xlarge, c3.2xlarge, c3.4xlarge, c3.8xlarge, c3.large, c3.xlarge, c4.2xlarge, c4.4xlarge, c4.large, c4.xlarge, m1.large, m1.medium, m1.small, m1.xlarge, m2.2xlarge, m2.4xlarge, m2.xlarge, m3.2xlarge, m3.large, m3.medium, m3.xlarge, m4.10xlarge, m4.2xlarge, m4.4xlarge, m4.large, m4.xlarge, t1.micro, t2.large, t2.medium, t2.micro, t2.nano, t2.small, t3.2xlarge\n" - printf " Default: t3.2xlarge\n" + printf " %s\n" "Allowed: c1.medium, c1.xlarge, c3.2xlarge, c3.4xlarge, c3.8xlarge, c3.large, c3.xlarge, c4.2xlarge, c4.4xlarge, c4.large, c4.xlarge, m1.large, m1.medium, m1.small, m1.xlarge, m2.2xlarge, m2.4xlarge, m2.xlarge, m3.2xlarge, m3.large, m3.medium, m3.xlarge, m4.10xlarge, m4.2xlarge, m4.4xlarge, m4.large, m4.xlarge, t1.micro, t2.large, t2.medium, t2.micro, t2.nano, t2.small, t3.2xlarge" + printf " %s\n" "Default: t3.2xlarge" echo # :flag.usage printf " %s\n" "$(magenta "--size SIZE")" printf " 💾 instance size in Gb. default is 1000 Gb\n" - printf " Default: 1000\n" + printf " %s\n" "Default: 1000" echo # :flag.usage @@ -5782,7 +5805,7 @@ playground_ec2_delete_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5814,7 +5837,7 @@ playground_ec2_open_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5846,7 +5869,7 @@ playground_ec2_allow_my_ip_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5873,7 +5896,7 @@ playground_ec2_list_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -5894,7 +5917,7 @@ playground_ec2_stop_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5921,7 +5944,7 @@ playground_ec2_start_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5948,7 +5971,7 @@ playground_ec2_status_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -5990,7 +6013,7 @@ playground_ec2_sync_repro_folder_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_fixed_flags @@ -6011,7 +6034,7 @@ playground_ec2_sync_repro_folder_local_to_ec2_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -6038,7 +6061,7 @@ playground_ec2_sync_repro_folder_ec2_to_local_usage() { echo # :command.long_usage - if [[ -n $long_usage ]]; then + if [[ -n "$long_usage" ]]; then printf "%s\n" "$(bold "== Options ==")" # :command.usage_flags @@ -6058,7 +6081,7 @@ playground_ec2_sync_repro_folder_ec2_to_local_usage() { # :command.normalize_input # :command.normalize_input_function normalize_input() { - local arg flags passthru + local arg passthru flags passthru=false while [[ $# -gt 0 ]]; do @@ -8033,6 +8056,11 @@ function version_gt() { function set_kafka_client_tag() { + if [[ $TAG_BASE = 7.7.* ]] + then + export KAFKA_CLIENT_TAG="3.7.0" + fi + if [[ $TAG_BASE = 7.6.* ]] then export KAFKA_CLIENT_TAG="3.6.0" @@ -15886,6 +15914,12 @@ EOF log "Cleanup Salesforce Contacts on account with $SALESFORCE_USERNAME" docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME\" -p \"$SALESFORCE_PASSWORD\" -r \"$SALESFORCE_INSTANCE\" -s \"$SALESFORCE_SECURITY_TOKEN\" && sfdx data:query --target-org \"$SALESFORCE_USERNAME\" -q \"SELECT Id FROM Contact\" --result-format csv > /tmp/out.csv && sfdx force:data:bulk:delete --target-org \"$SALESFORCE_USERNAME\" -s Contact -f /tmp/out.csv" + + log "Cleanup PushTopics on account with $SALESFORCE_USERNAME" + docker exec -i sfdx-cli sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME\"" << EOF +List pts = [SELECT Id FROM PushTopic]; +Database.delete(pts); +EOF fi SALESFORCE_INSTANCE_ACCOUNT2=${SALESFORCE_INSTANCE_ACCOUNT2:-"https://login.salesforce.com"} @@ -15896,6 +15930,12 @@ EOF log "Cleanup Salesforce Contacts on account with $SALESFORCE_USERNAME_ACCOUNT2" docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME_ACCOUNT2\" -p \"$SALESFORCE_PASSWORD_ACCOUNT2\" -r \"$SALESFORCE_INSTANCE_ACCOUNT2\" -s \"$SALESFORCE_SECURITY_TOKEN_ACCOUNT2\" && sfdx data:query --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\" -q \"SELECT Id FROM Contact\" --result-format csv > /tmp/out.csv && sfdx force:data:bulk:delete --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\" -s Contact -f /tmp/out.csv" + + log "Cleanup PushTopics on account with $SALESFORCE_USERNAME_ACCOUNT2" + docker exec -i sfdx-cli sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\"" << EOF +List pts = [SELECT Id FROM PushTopic]; +Database.delete(pts); +EOF fi } @@ -18668,6 +18708,7 @@ playground_debug_heap_dump_command() { logerror "❌ Failed to take heap dump" fi fi + } # :command.function @@ -19425,6 +19466,7 @@ playground_topic_get_number_records_command() { fi fi done + } # :command.function @@ -23750,6 +23792,7 @@ playground_connector_snippets_command() { fi fi fi + } # :command.function @@ -24324,6 +24367,7 @@ then fi playground connector show-lag --connector $connector fi + } # :command.function @@ -27614,6 +27658,7 @@ playground_config_folder_zip_or_jar_parse_requirements() { # :command.validations # :argument.validations if [[ -v args['folder'] ]]; then + values='' eval "values=(${args['folder']})" for value in "${values[@]}"; do if [[ -n $(validate_dir_exists "$value") ]]; then @@ -29039,6 +29084,7 @@ playground_cleanup_cloud_resources_parse_requirements() { [[ -n ${args['--resource']:-} ]] || args['--resource']="aws gcp azure ccloud salesforce" # :command.whitelist_filter + input_array='' eval "input_array=(${args[--resource]})" for i in "${input_array[@]}"; do if [[ ! $i =~ ^(aws|gcp|azure|ccloud|salesforce)$ ]]; then @@ -29437,6 +29483,7 @@ playground_repro_bootstrap_parse_requirements() { # :flag.validations if [[ -v args['--pipeline'] ]]; then + values='' eval "values=(${args['--pipeline']})" for value in "${values[@]}"; do if [[ -n $(validate_file_exists_with_trick "$value") ]]; then @@ -35010,6 +35057,7 @@ playground_topic_produce_parse_requirements() { printf "%s\n" "--value-subject-name-strategy must be one of: TopicNameStrategy, RecordNameStrategy, TopicRecordNameStrategy" >&2 exit 1 fi + input_array='' eval "input_array=(${args[--validate-config]})" for i in "${input_array[@]}"; do if [[ ! $i =~ ^(scrub.invalid.names=true|enhanced.avro.schema.support=true|connect.meta.data=false|object.additional.properties=false|use.optional.for.nonrequired=true|ignore.default.for.nullables=true|generalized.sum.type.support=true|enhanced.protobuf.schema.support=true|generate.index.for.unions=false|int.for.enums=true|optional.for.nullables=true|generate.struct.for.nulls=true|wrapper.for.nullables=true|wrapper.for.raw.primitives=false)$ ]]; then diff --git a/scripts/cli/src/commands/cleanup-cloud-resources.sh b/scripts/cli/src/commands/cleanup-cloud-resources.sh index bc7a55aa6f..406273d8c4 100644 --- a/scripts/cli/src/commands/cleanup-cloud-resources.sh +++ b/scripts/cli/src/commands/cleanup-cloud-resources.sh @@ -261,6 +261,12 @@ function cleanup_salesforce () { log "Cleanup Salesforce Contacts on account with $SALESFORCE_USERNAME" docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME\" -p \"$SALESFORCE_PASSWORD\" -r \"$SALESFORCE_INSTANCE\" -s \"$SALESFORCE_SECURITY_TOKEN\" && sfdx data:query --target-org \"$SALESFORCE_USERNAME\" -q \"SELECT Id FROM Contact\" --result-format csv > /tmp/out.csv && sfdx force:data:bulk:delete --target-org \"$SALESFORCE_USERNAME\" -s Contact -f /tmp/out.csv" + + log "Cleanup PushTopics on account with $SALESFORCE_USERNAME" + docker exec -i sfdx-cli sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME\"" << EOF +List pts = [SELECT Id FROM PushTopic]; +Database.delete(pts); +EOF fi SALESFORCE_INSTANCE_ACCOUNT2=${SALESFORCE_INSTANCE_ACCOUNT2:-"https://login.salesforce.com"} @@ -271,6 +277,12 @@ function cleanup_salesforce () { log "Cleanup Salesforce Contacts on account with $SALESFORCE_USERNAME_ACCOUNT2" docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME_ACCOUNT2\" -p \"$SALESFORCE_PASSWORD_ACCOUNT2\" -r \"$SALESFORCE_INSTANCE_ACCOUNT2\" -s \"$SALESFORCE_SECURITY_TOKEN_ACCOUNT2\" && sfdx data:query --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\" -q \"SELECT Id FROM Contact\" --result-format csv > /tmp/out.csv && sfdx force:data:bulk:delete --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\" -s Contact -f /tmp/out.csv" + + log "Cleanup PushTopics on account with $SALESFORCE_USERNAME_ACCOUNT2" + docker exec -i sfdx-cli sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\"" << EOF +List pts = [SELECT Id FROM PushTopic]; +Database.delete(pts); +EOF fi } From d1dd445575c733f805e666837f027f2c36bfc766 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 12 Sep 2024 15:55:51 +0200 Subject: [PATCH 017/659] wip (#6) * minor * minor * delete topic * Add HTTP Source V2 Fully Managed example #5884 * sleep 60 * fix --- .github/workflows/ci.yml | 2 +- .../fully-managed-gcp-bigtable-sink.sh | 2 +- .../fully-managed-http-basic-auth.sh | 4 + .../fully-managed-http-sink-mtls-auth.sh | 4 + .../fully-managed-http-sink-oauth2.sh | 4 + .../fm-http-sink/fully-managed-http-sink.sh | 4 + .../fully-managed-http-source-oauth2.sh | 4 + .../fully-managed-http-v2-basic-auth.sh | 4 + .../fully-managed-http-v2-sink-mtls-auth.sh | 4 + .../fully-managed-http-v2-sink-oauth2.sh | 4 + .../fully-managed-http-v2-sink.sh | 4 + ccloud/fm-http-v2-source/README.md | 21 ++++ .../docker-compose.oauth2.yml | 32 +++++ .../fully-managed-http-source-v2-oauth2.sh | 117 ++++++++++++++++++ ccloud/fm-http-v2-source/ngrok.yml | 5 + ccloud/fm-http-v2-source/stop.sh | 10 ++ .../gcp-bigtable-sink-proxy.sh | 2 +- .../gcp-bigtable-sink.sh | 2 +- .../connect-jdbc-vertica-sink/vertica-sink.sh | 2 +- .../json-schemaless.sh | 20 +-- connect/connect-spool-dir-source/json.sh | 22 ++-- .../line-delimited.sh | 20 +-- connect/connect-spool-dir-source/tsv.sh | 24 ++-- docs/content-template.md | 1 + scripts/cli/confluent-kafka-region-list.txt | 1 + 25 files changed, 271 insertions(+), 48 deletions(-) create mode 100644 ccloud/fm-http-v2-source/README.md create mode 100644 ccloud/fm-http-v2-source/docker-compose.oauth2.yml create mode 100755 ccloud/fm-http-v2-source/fully-managed-http-source-v2-oauth2.sh create mode 100644 ccloud/fm-http-v2-source/ngrok.yml create mode 100755 ccloud/fm-http-v2-source/stop.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 72b4725006..24bd9a385c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -139,7 +139,7 @@ jobs: "🚀 connect/connect-jdbc-sap-hana-sink connect/connect-jdbc-sap-hana-source connect/connect-sap-hana-sink", # requiring ngrok - "🚀2️⃣ ccloud/fm-influxdb2-sink ccloud/fm-influxdb2-source ccloud/fm-jdbc-oracle19-source ccloud/fm-jdbc-oracle19-sink ccloud/fm-cdc-oracle19-source ccloud/fm-rabbitmq-source ccloud/fm-zendesk-source ccloud/fm-splunk-sink ccloud/fm-rabbitmq-sink ccloud/fm-jdbc-mysql-sink ccloud/fm-sftp-source ccloud/fm-http-sink ccloud/fm-http-v2-sink ccloud/fm-http-source", + "🚀2️⃣ ccloud/fm-influxdb2-sink ccloud/fm-influxdb2-source ccloud/fm-jdbc-oracle19-source ccloud/fm-jdbc-oracle19-sink ccloud/fm-cdc-oracle19-source ccloud/fm-rabbitmq-source ccloud/fm-zendesk-source ccloud/fm-splunk-sink ccloud/fm-rabbitmq-sink ccloud/fm-jdbc-mysql-sink ccloud/fm-sftp-source ccloud/fm-http-sink ccloud/fm-http-v2-sink ccloud/fm-http-source ccloud/fm-http-v2-source", "🚀3️⃣ ccloud/fm-cdc-oracle11-source ccloud/fm-solace-sink ccloud/fm-opensearch-sink ccloud/fm-sftp-sink ccloud/fm-redis-sink" ] steps: diff --git a/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh b/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh index 55fae5bdbf..75bd58c409 100755 --- a/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh +++ b/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh @@ -132,7 +132,7 @@ playground connector create-or-update --connector $connector_name << EOF EOF wait_for_ccloud_connector_up $connector_name 180 -sleep 30 +sleep 60 log "Verify data is in GCP BigTable" docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 diff --git a/ccloud/fm-http-sink/fully-managed-http-basic-auth.sh b/ccloud/fm-http-sink/fully-managed-http-basic-auth.sh index 8bc212692a..913972a294 100755 --- a/ccloud/fm-http-sink/fully-managed-http-basic-auth.sh +++ b/ccloud/fm-http-sink/fully-managed-http-basic-auth.sh @@ -43,6 +43,10 @@ do sleep 5 done +set +e +playground topic delete --topic http-topic +set -e + log "Creating http-topic topic in Confluent Cloud" set +e playground topic create --topic http-topic diff --git a/ccloud/fm-http-sink/fully-managed-http-sink-mtls-auth.sh b/ccloud/fm-http-sink/fully-managed-http-sink-mtls-auth.sh index 6ab2f549eb..521b984bcf 100755 --- a/ccloud/fm-http-sink/fully-managed-http-sink-mtls-auth.sh +++ b/ccloud/fm-http-sink/fully-managed-http-sink-mtls-auth.sh @@ -45,6 +45,10 @@ do sleep 5 done +set +e +playground topic delete --topic http-topic +set -e + log "Creating http-topic topic in Confluent Cloud" set +e playground topic create --topic http-topic diff --git a/ccloud/fm-http-sink/fully-managed-http-sink-oauth2.sh b/ccloud/fm-http-sink/fully-managed-http-sink-oauth2.sh index 557cc9e14d..50501f663e 100755 --- a/ccloud/fm-http-sink/fully-managed-http-sink-oauth2.sh +++ b/ccloud/fm-http-sink/fully-managed-http-sink-oauth2.sh @@ -45,6 +45,10 @@ do sleep 5 done +set +e +playground topic delete --topic http-topic +set -e + log "Creating http-topic topic in Confluent Cloud" set +e playground topic create --topic http-topic diff --git a/ccloud/fm-http-sink/fully-managed-http-sink.sh b/ccloud/fm-http-sink/fully-managed-http-sink.sh index b1a8e54753..3da9291efb 100755 --- a/ccloud/fm-http-sink/fully-managed-http-sink.sh +++ b/ccloud/fm-http-sink/fully-managed-http-sink.sh @@ -41,6 +41,10 @@ do sleep 5 done +set +e +playground topic delete --topic http-topic +set -e + log "Creating http-topic topic in Confluent Cloud" set +e playground topic create --topic http-topic diff --git a/ccloud/fm-http-source/fully-managed-http-source-oauth2.sh b/ccloud/fm-http-source/fully-managed-http-source-oauth2.sh index 5b24cb1587..dbe0528794 100755 --- a/ccloud/fm-http-source/fully-managed-http-source-oauth2.sh +++ b/ccloud/fm-http-source/fully-managed-http-source-oauth2.sh @@ -45,6 +45,10 @@ do sleep 5 done +set +e +playground topic delete --topic http-topic +set -e + log "Creating http-topic topic in Confluent Cloud" set +e playground topic create --topic http-topic diff --git a/ccloud/fm-http-v2-sink/fully-managed-http-v2-basic-auth.sh b/ccloud/fm-http-v2-sink/fully-managed-http-v2-basic-auth.sh index 6019b5116a..db638ca5bd 100755 --- a/ccloud/fm-http-v2-sink/fully-managed-http-v2-basic-auth.sh +++ b/ccloud/fm-http-v2-sink/fully-managed-http-v2-basic-auth.sh @@ -43,6 +43,10 @@ do sleep 5 done +set +e +playground topic delete --topic http-topic +set -e + log "Creating http-topic topic in Confluent Cloud" set +e playground topic create --topic http-topic diff --git a/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-mtls-auth.sh b/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-mtls-auth.sh index 5714d30a01..d49da800d5 100755 --- a/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-mtls-auth.sh +++ b/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-mtls-auth.sh @@ -45,6 +45,10 @@ do sleep 5 done +set +e +playground topic delete --topic http-topic +set -e + log "Creating http-topic topic in Confluent Cloud" set +e playground topic create --topic http-topic diff --git a/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-oauth2.sh b/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-oauth2.sh index 169896ac53..4a2b70632e 100755 --- a/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-oauth2.sh +++ b/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink-oauth2.sh @@ -45,6 +45,10 @@ do sleep 5 done +set +e +playground topic delete --topic http-topic +set -e + log "Creating http-topic topic in Confluent Cloud" set +e playground topic create --topic http-topic diff --git a/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink.sh b/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink.sh index 683a4eff6e..4d49095c91 100755 --- a/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink.sh +++ b/ccloud/fm-http-v2-sink/fully-managed-http-v2-sink.sh @@ -41,6 +41,10 @@ do sleep 5 done +set +e +playground topic delete --topic http-topic +set -e + log "Creating http-topic topic in Confluent Cloud" set +e playground topic create --topic http-topic diff --git a/ccloud/fm-http-v2-source/README.md b/ccloud/fm-http-v2-source/README.md new file mode 100644 index 0000000000..4d931cc60b --- /dev/null +++ b/ccloud/fm-http-v2-source/README.md @@ -0,0 +1,21 @@ +# Fully Managed HTTP V2 Source connector + + + +## Objective + +Quickly test [Fully Managed HTTP V2 Source](https://docs.confluent.io/cloud/current/connectors/cc-http-source-v2.html) connector. + + +## Prerequisites + +See [here](https://kafka-docker-playground.io/#/how-to-use?id=%f0%9f%8c%a4%ef%b8%8f-confluent-cloud-examples) + +## How to run + +Simply run: + +``` +$ just use command and search for fully-managed-http-source-oauth2.sh in this folder +``` + diff --git a/ccloud/fm-http-v2-source/docker-compose.oauth2.yml b/ccloud/fm-http-v2-source/docker-compose.oauth2.yml new file mode 100644 index 0000000000..d36a404263 --- /dev/null +++ b/ccloud/fm-http-v2-source/docker-compose.oauth2.yml @@ -0,0 +1,32 @@ +--- +services: + + httpserver: + image: vdesabou/http-sink-demo + hostname: httpserver + container_name: httpserver + ports: + - "18080:8080" + environment: + SPRING_PROFILES_ACTIVE: 'oauth2' + + # https://ngrok.com/docs/using-ngrok-with/docker/ + ngrok: + image: ngrok/ngrok:latest + hostname: ngrok + container_name: ngrok + ports: + - 4040:4040 + restart: unless-stopped + links: + - httpserver + command: + - "start" + - "--all" + - "--log=stdout" + - "--config" + - "/etc/ngrok.yml" + volumes: + - ../../ccloud/fm-http-source/ngrok.yml:/etc/ngrok.yml + environment: + NGROK_AUTHTOKEN: $NGROK_AUTH_TOKEN \ No newline at end of file diff --git a/ccloud/fm-http-v2-source/fully-managed-http-source-v2-oauth2.sh b/ccloud/fm-http-v2-source/fully-managed-http-source-v2-oauth2.sh new file mode 100755 index 0000000000..9e65714008 --- /dev/null +++ b/ccloud/fm-http-v2-source/fully-managed-http-source-v2-oauth2.sh @@ -0,0 +1,117 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +NGROK_AUTH_TOKEN=${NGROK_AUTH_TOKEN:-$1} + +display_ngrok_warning + +bootstrap_ccloud_environment + + + +docker compose -f docker-compose.oauth2.yml build +docker compose -f docker-compose.oauth2.yml down -v --remove-orphans +docker compose -f docker-compose.oauth2.yml up -d --quiet-pull + +sleep 5 + +log "Waiting for ngrok to start" +while true +do + container_id=$(docker ps -q -f name=ngrok) + if [ -n "$container_id" ] + then + status=$(docker inspect --format '{{.State.Status}}' $container_id) + if [ "$status" = "running" ] + then + log "Getting ngrok hostname and port" + NGROK_URL=$(curl --silent http://127.0.0.1:4040/api/tunnels | jq -r '.tunnels[0].public_url') + NGROK_HOSTNAME=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 1) + NGROK_PORT=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 2) + + if ! [[ $NGROK_PORT =~ ^[0-9]+$ ]] + then + log "NGROK_PORT is not a valid number, keep retrying..." + continue + else + break + fi + fi + fi + log "Waiting for container ngrok to start..." + sleep 5 +done + +set +e +playground topic delete --topic http-topic +set -e + +log "Creating http-topic topic in Confluent Cloud" +set +e +playground topic create --topic http-topic +set -e + +connector_name="HttpSourceV2_$USER" +set +e +playground connector delete --connector $connector_name > /dev/null 2>&1 +set -e + +log "Creating fully managed connector" +playground connector create-or-update --connector $connector_name << EOF +{ + "connector.class": "HttpSourceV2", + "name": "$connector_name", + "kafka.auth.mode": "KAFKA_API_KEY", + "kafka.api.key": "$CLOUD_KEY", + "kafka.api.secret": "$CLOUD_SECRET", + "output.data.format": "AVRO", + "http.api.base.url": "http://$NGROK_HOSTNAME:$NGROK_PORT/api/messages", + "tasks.max" : "1", + + "http.api.base.url": "http://$NGROK_HOSTNAME:$NGROK_PORT", + "behavior.on.error": "FAIL", + "apis.num": "1", + "api1.http.api.path": "/api/messages", + "api1.topics": "http-topic", + "api1.http.request.headers": "Content-Type: application/json", + "api1.test.api": "false", + "auth.type": "OAUTH2", + "oauth2.token.url": "http://$NGROK_HOSTNAME:$NGROK_PORT/oauth/token", + "oauth2.client.id": "kc-client", + "oauth2.client.secret": "kc-secret", + "oauth2.client.mode": "header", + "api1.http.offset.mode": "SIMPLE_INCREMENTING", + "api1.http.initial.offset": "0" +} +EOF +wait_for_ccloud_connector_up $connector_name 180 + +# create token, see https://github.com/confluentinc/kafka-connect-http-demo#oauth2 +token=$(curl -X POST \ + http://localhost:18080/oauth/token \ + -H 'Content-Type: application/x-www-form-urlencoded' \ + -H 'Authorization: Basic a2MtY2xpZW50OmtjLXNlY3JldA==' \ + -d 'grant_type=client_credentials&scope=any' | jq -r '.access_token') + + +log "Send a message to HTTP server" +curl -X PUT \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${token}" \ + --data '{"test":"value"}' \ + http://localhost:18080/api/messages | jq . + + +sleep 2 + +log "Verify we have received the data in http-topic topic" +playground topic consume --topic http-topic --min-expected-messages 1 --timeout 60 + + +log "Do you want to delete the fully managed connector $connector_name ?" +check_if_continue + +playground connector delete --connector $connector_name diff --git a/ccloud/fm-http-v2-source/ngrok.yml b/ccloud/fm-http-v2-source/ngrok.yml new file mode 100644 index 0000000000..a2893217cd --- /dev/null +++ b/ccloud/fm-http-v2-source/ngrok.yml @@ -0,0 +1,5 @@ +version: 2 +tunnels: + httpserver: + addr: httpserver:8080 + proto: tcp \ No newline at end of file diff --git a/ccloud/fm-http-v2-source/stop.sh b/ccloud/fm-http-v2-source/stop.sh new file mode 100755 index 0000000000..1ff863e145 --- /dev/null +++ b/ccloud/fm-http-v2-source/stop.sh @@ -0,0 +1,10 @@ +#!/bin/bash + + + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +docker compose -f docker-compose.oauth2.yml down -v --remove-orphans + +maybe_delete_ccloud_environment \ No newline at end of file diff --git a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh index 55fe97122b..e5040ea3fb 100755 --- a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh +++ b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh @@ -121,7 +121,7 @@ playground connector create-or-update --connector gcp-bigtable-sink << EOF } EOF -sleep 30 +sleep 60 log "Verify data is in GCP BigTable" docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 diff --git a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh index db9eb09b40..9d15edc7f4 100755 --- a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh +++ b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh @@ -115,7 +115,7 @@ playground connector create-or-update --connector gcp-bigtable-sink << EOF } EOF -sleep 30 +sleep 60 log "Verify data is in GCP BigTable" docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 diff --git a/connect/connect-jdbc-vertica-sink/vertica-sink.sh b/connect/connect-jdbc-vertica-sink/vertica-sink.sh index 035029d787..30a010920a 100755 --- a/connect/connect-jdbc-vertica-sink/vertica-sink.sh +++ b/connect/connect-jdbc-vertica-sink/vertica-sink.sh @@ -58,7 +58,7 @@ sleep 10 log "Check data is in Vertica" docker exec -i vertica /opt/vertica/bin/vsql -hlocalhost -Udbadmin > /tmp/result.log 2>&1 <<-EOF -select * from mytable; +select * from docker.mytable; EOF cat /tmp/result.log grep "value1" /tmp/result.log diff --git a/connect/connect-spool-dir-source/json-schemaless.sh b/connect/connect-spool-dir-source/json-schemaless.sh index e2e3328951..955121c823 100755 --- a/connect/connect-spool-dir-source/json-schemaless.sh +++ b/connect/connect-spool-dir-source/json-schemaless.sh @@ -13,16 +13,16 @@ docker exec -i connect bash -c 'mkdir -p /tmp/data/input/ && mkdir -p /tmp/data/ log "Creating JSON Spool Dir Source connector" playground connector create-or-update --connector spool-dir << EOF { - "tasks.max": "1", - "connector.class": "com.github.jcustenborder.kafka.connect.spooldir.SpoolDirSchemaLessJsonSourceConnector", - "input.file.pattern": ".*\\\\.json", - "input.path": "/tmp/data/input", - "error.path": "/tmp/data/error", - "finished.path": "/tmp/data/finished", - "halt.on.error": "false", - "topic": "spooldir-schemaless-json-topic", - "value.converter": "org.apache.kafka.connect.storage.StringConverter" - } + "tasks.max": "1", + "connector.class": "com.github.jcustenborder.kafka.connect.spooldir.SpoolDirSchemaLessJsonSourceConnector", + "input.file.pattern": ".*\\\\.json", + "input.path": "/tmp/data/input", + "error.path": "/tmp/data/error", + "finished.path": "/tmp/data/finished", + "halt.on.error": "false", + "topic": "spooldir-schemaless-json-topic", + "value.converter": "org.apache.kafka.connect.storage.StringConverter" +} EOF diff --git a/connect/connect-spool-dir-source/json.sh b/connect/connect-spool-dir-source/json.sh index 76933bd591..069be73337 100755 --- a/connect/connect-spool-dir-source/json.sh +++ b/connect/connect-spool-dir-source/json.sh @@ -13,17 +13,17 @@ docker exec -i connect bash -c 'mkdir -p /tmp/data/input/ && mkdir -p /tmp/data/ log "Creating JSON Spool Dir Source connector" playground connector create-or-update --connector spool-dir << EOF { - "tasks.max": "1", - "connector.class": "com.github.jcustenborder.kafka.connect.spooldir.SpoolDirJsonSourceConnector", - "input.file.pattern": ".*\\\\.json", - "input.path": "/tmp/data/input", - "error.path": "/tmp/data/error", - "finished.path": "/tmp/data/finished", - "halt.on.error": "false", - "topic": "spooldir-json-topic", - "key.schema": "{\n \"name\" : \"com.example.users.UserKey\",\n \"type\" : \"STRUCT\",\n \"isOptional\" : false,\n \"fieldSchemas\" : {\n \"id\" : {\n \"type\" : \"INT64\",\n \"isOptional\" : false\n }\n }\n}", - "value.schema": "{\n \"name\" : \"com.example.users.User\",\n \"type\" : \"STRUCT\",\n \"isOptional\" : false,\n \"fieldSchemas\" : {\n \"id\" : {\n \"type\" : \"INT64\",\n \"isOptional\" : false\n },\n \"first_name\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n },\n \"last_name\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n },\n \"email\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n },\n \"gender\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n },\n \"ip_address\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n },\n \"last_login\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n },\n \"account_balance\" : {\n \"name\" : \"org.apache.kafka.connect.data.Decimal\",\n \"type\" : \"BYTES\",\n \"version\" : 1,\n \"parameters\" : {\n \"scale\" : \"2\"\n },\n \"isOptional\" : true\n },\n \"country\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n },\n \"favorite_color\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n }\n }\n}" - } + "tasks.max": "1", + "connector.class": "com.github.jcustenborder.kafka.connect.spooldir.SpoolDirJsonSourceConnector", + "input.file.pattern": ".*\\\\.json", + "input.path": "/tmp/data/input", + "error.path": "/tmp/data/error", + "finished.path": "/tmp/data/finished", + "halt.on.error": "false", + "topic": "spooldir-json-topic", + "key.schema": "{\n \"name\" : \"com.example.users.UserKey\",\n \"type\" : \"STRUCT\",\n \"isOptional\" : false,\n \"fieldSchemas\" : {\n \"id\" : {\n \"type\" : \"INT64\",\n \"isOptional\" : false\n }\n }\n}", + "value.schema": "{\n \"name\" : \"com.example.users.User\",\n \"type\" : \"STRUCT\",\n \"isOptional\" : false,\n \"fieldSchemas\" : {\n \"id\" : {\n \"type\" : \"INT64\",\n \"isOptional\" : false\n },\n \"first_name\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n },\n \"last_name\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n },\n \"email\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n },\n \"gender\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n },\n \"ip_address\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n },\n \"last_login\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n },\n \"account_balance\" : {\n \"name\" : \"org.apache.kafka.connect.data.Decimal\",\n \"type\" : \"BYTES\",\n \"version\" : 1,\n \"parameters\" : {\n \"scale\" : \"2\"\n },\n \"isOptional\" : true\n },\n \"country\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n },\n \"favorite_color\" : {\n \"type\" : \"STRING\",\n \"isOptional\" : true\n }\n }\n}" +} EOF diff --git a/connect/connect-spool-dir-source/line-delimited.sh b/connect/connect-spool-dir-source/line-delimited.sh index 94cecd4fce..8d239a2f64 100755 --- a/connect/connect-spool-dir-source/line-delimited.sh +++ b/connect/connect-spool-dir-source/line-delimited.sh @@ -13,16 +13,16 @@ docker exec -i connect bash -c 'mkdir -p /tmp/data/input/ && mkdir -p /tmp/data/ log "Creating Line Delimited Spool Dir Source connector" playground connector create-or-update --connector spool-dir << EOF { - "tasks.max": "1", - "connector.class": "com.github.jcustenborder.kafka.connect.spooldir.SpoolDirLineDelimitedSourceConnector", - "input.file.pattern": ".*\\\\.json", - "input.path": "/tmp/data/input", - "error.path": "/tmp/data/error", - "finished.path": "/tmp/data/finished", - "halt.on.error": "false", - "topic": "fix-topic", - "schema.generation.enabled": "true" - } + "tasks.max": "1", + "connector.class": "com.github.jcustenborder.kafka.connect.spooldir.SpoolDirLineDelimitedSourceConnector", + "input.file.pattern": ".*\\\\.json", + "input.path": "/tmp/data/input", + "error.path": "/tmp/data/error", + "finished.path": "/tmp/data/finished", + "halt.on.error": "false", + "topic": "fix-topic", + "schema.generation.enabled": "true" +} EOF diff --git a/connect/connect-spool-dir-source/tsv.sh b/connect/connect-spool-dir-source/tsv.sh index ca8011509c..1843e16586 100755 --- a/connect/connect-spool-dir-source/tsv.sh +++ b/connect/connect-spool-dir-source/tsv.sh @@ -13,18 +13,18 @@ docker exec -i connect bash -c 'mkdir -p /tmp/data/input/ && mkdir -p /tmp/data/ log "Creating TSV Spool Dir Source connector" playground connector create-or-update --connector TsvSpoolDir << EOF { - "tasks.max": "1", - "connector.class": "com.github.jcustenborder.kafka.connect.spooldir.SpoolDirCsvSourceConnector", - "input.file.pattern": "tsv-spooldir-source.tsv", - "input.path": "/tmp/data/input", - "error.path": "/tmp/data/error", - "finished.path": "/tmp/data/finished", - "halt.on.error": "false", - "topic": "spooldir-tsv-topic", - "schema.generation.enabled": "true", - "csv.first.row.as.header": "true", - "csv.separator.char": "9" - } + "tasks.max": "1", + "connector.class": "com.github.jcustenborder.kafka.connect.spooldir.SpoolDirCsvSourceConnector", + "input.file.pattern": "tsv-spooldir-source.tsv", + "input.path": "/tmp/data/input", + "error.path": "/tmp/data/error", + "finished.path": "/tmp/data/finished", + "halt.on.error": "false", + "topic": "spooldir-tsv-topic", + "schema.generation.enabled": "true", + "csv.first.row.as.header": "true", + "csv.separator.char": "9" +} EOF diff --git a/docs/content-template.md b/docs/content-template.md index 081a3f28ab..bd213bf420 100644 --- a/docs/content-template.md +++ b/docs/content-template.md @@ -226,6 +226,7 @@ - [HTTP Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-http-sink) :ccloud/fm-http-sink: - [HTTP V2 Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-http-v2-sink) :ccloud/fm-http-v2-sink: - [HTTP Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-http-source) :ccloud/fm-http-source: + - [HTTP V2 Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-http-v2-source) :ccloud/fm-http-v2-source: - [IBM MQ Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-ibm-mq-source) :ccloud/fm-ibm-mq-source: - [InfluxDB 2 Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-influxdb2-source) :ccloud/fm-influxdb2-source: - [InfluxDB 2 Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-influxdb2-sink) :ccloud/fm-influxdb2-sink: diff --git a/scripts/cli/confluent-kafka-region-list.txt b/scripts/cli/confluent-kafka-region-list.txt index dc40f725ed..518e686afa 100644 --- a/scripts/cli/confluent-kafka-region-list.txt +++ b/scripts/cli/confluent-kafka-region-list.txt @@ -73,6 +73,7 @@ Singapore(ap-southeast-1)/ap-southeast-1 Singapore(asia-southeast1)/asia-southeast1 Singapore(southeastasia)/southeastasia Spain(eu-south-2)/eu-south-2 +Spain(spaincentral)/spaincentral Stockholm(eu-north-1)/eu-north-1 Sydney(ap-southeast-2)/ap-southeast-2 Sydney(australia-southeast1)/australia-southeast1 From f98cc07e5340325f621ead8e51c3551889e5c0c4 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 13 Sep 2024 16:04:21 +0200 Subject: [PATCH 018/659] wip (#7) * debug * MyLeadPushTopicsV2 * wip * 7.7.1 * playground connector show-lag --- .github/workflows/ci.yml | 6 +++--- .../fully-managed-gcp-bigtable-sink.sh | 2 +- .../fully-managed-salesforce-bulkapi-2-0-sink.sh | 2 +- .../azure-functions-sink.sh | 9 +++++---- .../gcp-bigtable-sink-proxy.sh | 2 +- .../connect-gcp-bigtable-sink/gcp-bigtable-sink.sh | 2 +- scripts/cli/tag-list.txt | 14 +++++++++++--- scripts/utils.sh | 2 +- 8 files changed, 24 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24bd9a385c..8e99744083 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: strategy: fail-fast: false matrix: - tag: ["7.7.0"] + tag: ["7.7.1"] test_list : [ # requiring ngrok "🚀1️⃣ ccloud/fm-debezium-mysql-legacy-source ccloud/fm-debezium-postgresql-legacy-source ccloud/fm-debezium-mysql-v2-source ccloud/fm-debezium-sqlserver-legacy-source ccloud/fm-debezium-sqlserver-v2-source ccloud/fm-elasticsearch-sink ccloud/fm-jdbc-sqlserver-sink ccloud/fm-jdbc-sqlserver-source ccloud/fm-ibm-mq-source ccloud/fm-jdbc-mysql-source ccloud/fm-jdbc-postgresql-sink ccloud/fm-mqtt-source ccloud/fm-debezium-postgresql-v2-source ccloud/fm-jdbc-postgresql-source", @@ -326,7 +326,7 @@ jobs: strategy: fail-fast: false matrix: - tag: ["7.7.0"] + tag: ["7.7.1"] test_list : [ "🚀 ${{ github.event.inputs.test_name }}" ] @@ -595,7 +595,7 @@ jobs: - name: Update README run: | cd ./scripts/cli - ./playground update-readme --tags "7.7.0" + ./playground update-readme --tags "7.7.1" env: GH_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} diff --git a/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh b/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh index 75bd58c409..066bb13488 100755 --- a/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh +++ b/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh @@ -132,7 +132,7 @@ playground connector create-or-update --connector $connector_name << EOF EOF wait_for_ccloud_connector_up $connector_name 180 -sleep 60 +playground connector show-lag --connector $connector_name --max-wait 360 log "Verify data is in GCP BigTable" docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 diff --git a/ccloud/fm-salesforce-bulkapi-2-0-sink/fully-managed-salesforce-bulkapi-2-0-sink.sh b/ccloud/fm-salesforce-bulkapi-2-0-sink/fully-managed-salesforce-bulkapi-2-0-sink.sh index e0c73cd934..fe74610a33 100755 --- a/ccloud/fm-salesforce-bulkapi-2-0-sink/fully-managed-salesforce-bulkapi-2-0-sink.sh +++ b/ccloud/fm-salesforce-bulkapi-2-0-sink/fully-managed-salesforce-bulkapi-2-0-sink.sh @@ -66,7 +66,7 @@ then exit 1 fi -PUSH_TOPICS_NAME=MyLeadPushTopics${TAG} +PUSH_TOPICS_NAME=MyLeadPushTopicsV2${TAG} PUSH_TOPICS_NAME=${PUSH_TOPICS_NAME//[-._]/} sed -e "s|:PUSH_TOPIC_NAME:|$PUSH_TOPICS_NAME|g" \ diff --git a/connect/connect-azure-functions-sink/azure-functions-sink.sh b/connect/connect-azure-functions-sink/azure-functions-sink.sh index 027a7e88a9..96cbb810e9 100755 --- a/connect/connect-azure-functions-sink/azure-functions-sink.sh +++ b/connect/connect-azure-functions-sink/azure-functions-sink.sh @@ -90,12 +90,13 @@ done output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions $AZURE_FUNCTIONS_NAME --show-keys") -FUNCTIONS_URL=$(echo $output | grep -Eo 'https://[^ >]+'|head -1) +FUNCTIONS_URL=$(echo "$output" | grep -Eo 'https://[^ >]+'|head -1) -if [ -z "$GITHUB_RUN_NUMBER" ] -then +echo "$output" +# if [ -z "$GITHUB_RUN_NUMBER" ] +# then log "Functions URL is $FUNCTIONS_URL" -fi +# fi PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" diff --git a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh index e5040ea3fb..cf9ed458c4 100755 --- a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh +++ b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh @@ -121,7 +121,7 @@ playground connector create-or-update --connector gcp-bigtable-sink << EOF } EOF -sleep 60 +playground connector show-lag --connector gcp-bigtable-sink --max-wait 360 log "Verify data is in GCP BigTable" docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 diff --git a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh index 9d15edc7f4..c0135c62a8 100755 --- a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh +++ b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh @@ -115,7 +115,7 @@ playground connector create-or-update --connector gcp-bigtable-sink << EOF } EOF -sleep 60 +playground connector show-lag --connector gcp-bigtable-sink --max-wait 360 log "Verify data is in GCP BigTable" docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 diff --git a/scripts/cli/tag-list.txt b/scripts/cli/tag-list.txt index a8a6a36591..b29b2964cf 100644 --- a/scripts/cli/tag-list.txt +++ b/scripts/cli/tag-list.txt @@ -14,7 +14,7 @@ 5.3.4-1 5.3.4-10 5.3.5 -5.3.5-1 +5.3.5-15.4.4 5.3.5-2 5.3.6 5.3.6-1 @@ -33,7 +33,6 @@ 5.4.10 5.4.2 5.4.3 -5.4.4 5.4.5 5.4.6 5.4.7 @@ -44,6 +43,7 @@ 5.5.10 5.5.11 5.5.12 +5.5.2 5.5.3 5.5.4 5.5.5 @@ -66,6 +66,7 @@ 6.0.6 6.0.7 6.0.8 +6.0.9 6.1.0 6.1.1 6.1.10 @@ -77,9 +78,11 @@ 6.1.2 6.1.3 6.1.4 +6.1.5 6.1.6 6.1.7 6.1.8 +6.1.9 6.2.0 6.2.1 6.2.10 @@ -102,7 +105,9 @@ 7.0.11 7.0.12 7.0.13 +7.0.14 7.0.15 +7.0.16 7.0.2 7.0.3 7.0.4 @@ -117,6 +122,7 @@ 7.1.11 7.1.12 7.1.13 +7.1.14 7.1.2 7.1.3 7.1.4 @@ -129,6 +135,7 @@ 7.2.1 7.2.10 7.2.11 +7.2.12 7.2.2 7.2.3 7.2.4 @@ -154,7 +161,7 @@ 7.4.4 7.4.5 7.4.6 -7.5.0 +7.4.7 7.5.1 7.5.2 7.5.3 @@ -164,3 +171,4 @@ 7.6.1 7.6.2 7.7.0 +7.7.1 diff --git a/scripts/utils.sh b/scripts/utils.sh index dc031bf668..6ccad08ae0 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -27,7 +27,7 @@ fi if [ -z "$TAG" ] then # TAG is not set, use default: - export TAG=7.7.0 # default tag + export TAG=7.7.1 # default tag # to handle ubi8 images export TAG_BASE=$TAG if [ -z "$CP_KAFKA_IMAGE" ] From 58dea86dfb445f5e50174eaa139239a40eadeae4 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 16 Sep 2024 14:58:07 +0200 Subject: [PATCH 019/659] wip (#8) * doing auth again * 3.25.1 * wip * wip * jdk 17 fix --- .../fully-managed-azure-functions-sink.sh | 2 +- .../fully-managed-gcp-bigtable-sink.sh | 6 ++++++ .../connect-azure-functions-sink/azure-functions-sink.sh | 2 +- .../connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh | 6 ++++++ connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh | 6 ++++++ .../docker-compose.plaintext.yml | 4 +++- other/schema-format-protobuf-with-key/producer/pom.xml | 2 +- other/schema-format-protobuf/producer/pom.xml | 2 +- scripts/cli/tag-list.txt | 8 ++++++-- 9 files changed, 31 insertions(+), 7 deletions(-) diff --git a/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh b/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh index 9bd75f316c..2ae2268412 100755 --- a/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh +++ b/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh @@ -90,7 +90,7 @@ done output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions $AZURE_FUNCTIONS_NAME --show-keys") -FUNCTIONS_URL=$(echo $output | grep -Eo 'https://[^ >]+'|head -1) +FUNCTIONS_URL=$(echo "$output" | grep "Invoke url" | grep -Eo 'https://[^ >]+'|head -1) if [ -z "$GITHUB_RUN_NUMBER" ] then diff --git a/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh b/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh index 066bb13488..b21cf4bec4 100755 --- a/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh +++ b/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh @@ -134,6 +134,12 @@ wait_for_ccloud_connector_up $connector_name 180 playground connector show-lag --connector $connector_name --max-wait 360 +log "Doing gsutil authentication" +set +e +docker rm -f gcloud-config +set -e +docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cloud-sdk:latest gcloud auth activate-service-account --project ${GCP_PROJECT} --key-file /tmp/keyfile.json + log "Verify data is in GCP BigTable" docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 cat /tmp/result.log diff --git a/connect/connect-azure-functions-sink/azure-functions-sink.sh b/connect/connect-azure-functions-sink/azure-functions-sink.sh index 96cbb810e9..4354d68f9a 100755 --- a/connect/connect-azure-functions-sink/azure-functions-sink.sh +++ b/connect/connect-azure-functions-sink/azure-functions-sink.sh @@ -90,7 +90,7 @@ done output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions $AZURE_FUNCTIONS_NAME --show-keys") -FUNCTIONS_URL=$(echo "$output" | grep -Eo 'https://[^ >]+'|head -1) +FUNCTIONS_URL=$(echo "$output" | grep "Invoke url" | grep -Eo 'https://[^ >]+'|head -1) echo "$output" # if [ -z "$GITHUB_RUN_NUMBER" ] diff --git a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh index cf9ed458c4..ecdf7773b6 100755 --- a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh +++ b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh @@ -123,6 +123,12 @@ EOF playground connector show-lag --connector gcp-bigtable-sink --max-wait 360 +log "Doing gsutil authentication" +set +e +docker rm -f gcloud-config +set -e +docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cloud-sdk:latest gcloud auth activate-service-account --project ${GCP_PROJECT} --key-file /tmp/keyfile.json + log "Verify data is in GCP BigTable" docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 cat /tmp/result.log diff --git a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh index c0135c62a8..56b0b9b44f 100755 --- a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh +++ b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh @@ -117,6 +117,12 @@ EOF playground connector show-lag --connector gcp-bigtable-sink --max-wait 360 +log "Doing gsutil authentication" +set +e +docker rm -f gcloud-config +set -e +docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cloud-sdk:latest gcloud auth activate-service-account --project ${GCP_PROJECT} --key-file /tmp/keyfile.json + log "Verify data is in GCP BigTable" docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 cat /tmp/result.log diff --git a/connect/connect-jdbc-snowflake-source/docker-compose.plaintext.yml b/connect/connect-jdbc-snowflake-source/docker-compose.plaintext.yml index 2bd1f4b8ec..22d5ebfaeb 100644 --- a/connect/connect-jdbc-snowflake-source/docker-compose.plaintext.yml +++ b/connect/connect-jdbc-snowflake-source/docker-compose.plaintext.yml @@ -6,4 +6,6 @@ services: - ../../connect/connect-jdbc-snowflake-source/snowflake_key.p8:/tmp/snowflake_key.p8 - ../../connect/connect-jdbc-snowflake-source/snowflake-jdbc-3.13.16.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/snowflake-jdbc-3.13.16.jar environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file + CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc + # JDK 17 + KAFKA_OPTS: --add-opens java.base/java.nio=ALL-UNNAMED \ No newline at end of file diff --git a/other/schema-format-protobuf-with-key/producer/pom.xml b/other/schema-format-protobuf-with-key/producer/pom.xml index 8dfce3d981..46ff79a763 100644 --- a/other/schema-format-protobuf-with-key/producer/pom.xml +++ b/other/schema-format-protobuf-with-key/producer/pom.xml @@ -11,7 +11,7 @@ 1.8 UTF-8 UTF-8 - 3.24.4 + 3.25.1 3.11.4 6.2.0 2.8.0 diff --git a/other/schema-format-protobuf/producer/pom.xml b/other/schema-format-protobuf/producer/pom.xml index 8dfce3d981..46ff79a763 100644 --- a/other/schema-format-protobuf/producer/pom.xml +++ b/other/schema-format-protobuf/producer/pom.xml @@ -11,7 +11,7 @@ 1.8 UTF-8 UTF-8 - 3.24.4 + 3.25.1 3.11.4 6.2.0 2.8.0 diff --git a/scripts/cli/tag-list.txt b/scripts/cli/tag-list.txt index b29b2964cf..925fd165c9 100644 --- a/scripts/cli/tag-list.txt +++ b/scripts/cli/tag-list.txt @@ -14,7 +14,7 @@ 5.3.4-1 5.3.4-10 5.3.5 -5.3.5-15.4.4 +5.3.5-1 5.3.5-2 5.3.6 5.3.6-1 @@ -33,6 +33,7 @@ 5.4.10 5.4.2 5.4.3 +5.4.4 5.4.5 5.4.6 5.4.7 @@ -75,7 +76,6 @@ 6.1.13 6.1.14 6.1.15 -6.1.2 6.1.3 6.1.4 6.1.5 @@ -146,6 +146,7 @@ 7.2.9 7.3.0 7.3.1 +7.3.10 7.3.2 7.3.3 7.3.4 @@ -162,13 +163,16 @@ 7.4.5 7.4.6 7.4.7 +7.5.0 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 +7.5.6 7.6.0 7.6.1 7.6.2 +7.6.3 7.7.0 7.7.1 From 10e2ca2a9c36994d0fe311b50eadd0d7c6c3a5ca Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 17 Sep 2024 16:04:24 +0200 Subject: [PATCH 020/659] 16092024 2 (#9) * Add example for jsonata #5756 * check does not work with CI for some reasons, only relying on lag * Issue with adding tcpdump #5917 --- .github/workflows/ci.yml | 2 +- .../fully-managed-gcp-bigtable-sink.sh | 22 ++++--- .../gcp-bigtable-sink-proxy.sh | 24 ++++--- .../gcp-bigtable-sink.sh | 22 ++++--- docs/content-template.md | 1 + other/kafka-connect-jsonata/README.md | 7 +++ .../docker-compose.plaintext.yml | 5 ++ .../jsonata-drop-tombstone.sh | 62 +++++++++++++++++++ scripts/cli/src/lib/utils_function.sh | 2 +- 9 files changed, 117 insertions(+), 30 deletions(-) create mode 100644 other/kafka-connect-jsonata/README.md create mode 100644 other/kafka-connect-jsonata/docker-compose.plaintext.yml create mode 100755 other/kafka-connect-jsonata/jsonata-drop-tombstone.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8e99744083..389fa5021c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -136,7 +136,7 @@ jobs: "🚀 environment/plaintext environment/2way-ssl environment/kerberos environment/ldap-authorizer-sasl-plain environment/ldap-sasl-plain environment/mdc-kerberos environment/mdc-plaintext environment/mdc-sasl-plain environment/rbac-sasl-plain environment/sasl-plain environment/sasl-scram environment/sasl-ssl environment/ssl_kerberos environment/kraft-plaintext connect/connect-snowflake-sink", "🚀 connect/connect-mapr-sink", "🚀 other/syslog-logstash-ksqldb other/mqtt-proxy connect/connect-jdbc-snowflake-source connect/connect-jdbc-snowflake-sink connect/connect-filestream-source connect/connect-filestream-sink connect/connect-filepulse-source connect/connect-jdbc-mariadb-source connect/connect-jdbc-mariadb-sink", - "🚀 connect/connect-jdbc-sap-hana-sink connect/connect-jdbc-sap-hana-source connect/connect-sap-hana-sink", + "🚀 connect/connect-jdbc-sap-hana-sink connect/connect-jdbc-sap-hana-source connect/connect-sap-hana-sink other/kafka-connect-jsonata", # requiring ngrok "🚀2️⃣ ccloud/fm-influxdb2-sink ccloud/fm-influxdb2-source ccloud/fm-jdbc-oracle19-source ccloud/fm-jdbc-oracle19-sink ccloud/fm-cdc-oracle19-source ccloud/fm-rabbitmq-source ccloud/fm-zendesk-source ccloud/fm-splunk-sink ccloud/fm-rabbitmq-sink ccloud/fm-jdbc-mysql-sink ccloud/fm-sftp-source ccloud/fm-http-sink ccloud/fm-http-v2-sink ccloud/fm-http-source ccloud/fm-http-v2-source", diff --git a/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh b/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh index b21cf4bec4..6c3b4e7317 100755 --- a/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh +++ b/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh @@ -134,16 +134,20 @@ wait_for_ccloud_connector_up $connector_name 180 playground connector show-lag --connector $connector_name --max-wait 360 -log "Doing gsutil authentication" -set +e -docker rm -f gcloud-config -set -e -docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cloud-sdk:latest gcloud auth activate-service-account --project ${GCP_PROJECT} --key-file /tmp/keyfile.json +if [ -z "$GITHUB_RUN_NUMBER" ] +then + # not running with github actions + log "Doing gsutil authentication" + set +e + docker rm -f gcloud-config + set -e + docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cloud-sdk:latest gcloud auth activate-service-account --project ${GCP_PROJECT} --key-file /tmp/keyfile.json -log "Verify data is in GCP BigTable" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 -cat /tmp/result.log -grep "Bob" /tmp/result.log + log "Verify data is in GCP BigTable" + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 + cat /tmp/result.log + grep "Bob" /tmp/result.log +fi log "Do you want to delete the fully managed connector $connector_name ?" check_if_continue diff --git a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh index ecdf7773b6..1a7671f6c0 100755 --- a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh +++ b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh @@ -123,13 +123,17 @@ EOF playground connector show-lag --connector gcp-bigtable-sink --max-wait 360 -log "Doing gsutil authentication" -set +e -docker rm -f gcloud-config -set -e -docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cloud-sdk:latest gcloud auth activate-service-account --project ${GCP_PROJECT} --key-file /tmp/keyfile.json - -log "Verify data is in GCP BigTable" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 -cat /tmp/result.log -grep "Bob" /tmp/result.log \ No newline at end of file +if [ -z "$GITHUB_RUN_NUMBER" ] +then + # not running with github actions + log "Doing gsutil authentication" + set +e + docker rm -f gcloud-config + set -e + docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cloud-sdk:latest gcloud auth activate-service-account --project ${GCP_PROJECT} --key-file /tmp/keyfile.json + + log "Verify data is in GCP BigTable" + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 + cat /tmp/result.log + grep "Bob" /tmp/result.log +fi \ No newline at end of file diff --git a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh index 56b0b9b44f..471a8b9ac3 100755 --- a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh +++ b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh @@ -117,13 +117,17 @@ EOF playground connector show-lag --connector gcp-bigtable-sink --max-wait 360 -log "Doing gsutil authentication" -set +e -docker rm -f gcloud-config -set -e -docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cloud-sdk:latest gcloud auth activate-service-account --project ${GCP_PROJECT} --key-file /tmp/keyfile.json +if [ -z "$GITHUB_RUN_NUMBER" ] +then + # not running with github actions + log "Doing gsutil authentication" + set +e + docker rm -f gcloud-config + set -e + docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cloud-sdk:latest gcloud auth activate-service-account --project ${GCP_PROJECT} --key-file /tmp/keyfile.json -log "Verify data is in GCP BigTable" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 -cat /tmp/result.log -grep "Bob" /tmp/result.log \ No newline at end of file + log "Verify data is in GCP BigTable" + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 + cat /tmp/result.log + grep "Bob" /tmp/result.log +fi \ No newline at end of file diff --git a/docs/content-template.md b/docs/content-template.md index bd213bf420..e7a7475f4e 100644 --- a/docs/content-template.md +++ b/docs/content-template.md @@ -416,3 +416,4 @@ Using Multi-Data-Center setup with 🇺🇸 and 🇪🇺 clusters - 🪦 [Recovery from schema hard deletion](https://github.com/vdesabou/kafka-docker-playground/tree/master/other/recover-from-schema-hard-deletion) ![not tested](https://img.shields.io/badge/CI-not%20tested!-violet) - 🔍 [ksqlDB Schema Inference with ID](https://github.com/vdesabou/kafka-docker-playground/tree/master/ksqldb/schema-inference-with-id) ![not tested](https://img.shields.io/badge/CI-not%20tested!-violet) - 💬 [MQTT Proxy](https://github.com/vdesabou/kafka-docker-playground/tree/master/other/mqtt-proxy) :other/mqtt-proxy: +- 💱 [Kafka Connect JSONata Transform](https://github.com/vdesabou/kafka-docker-playground/tree/master/other/kafka-connect-jsonata) :other/kafka-connect-jsonata: \ No newline at end of file diff --git a/other/kafka-connect-jsonata/README.md b/other/kafka-connect-jsonata/README.md new file mode 100644 index 0000000000..85e08d8187 --- /dev/null +++ b/other/kafka-connect-jsonata/README.md @@ -0,0 +1,7 @@ +# kafka-connect-jsonata SMT + + + +## Objective + +Quickly test [kafka-connect-jsonata](https://github.com/rayokota/kafka-connect-jsonata) SMT. diff --git a/other/kafka-connect-jsonata/docker-compose.plaintext.yml b/other/kafka-connect-jsonata/docker-compose.plaintext.yml new file mode 100644 index 0000000000..c26274dc9d --- /dev/null +++ b/other/kafka-connect-jsonata/docker-compose.plaintext.yml @@ -0,0 +1,5 @@ +--- +services: + connect: + environment: + CONNECT_PLUGIN_PATH: /usr/share/filestream-connectors,/usr/share/confluent-hub-components/rayokota-kafka-connect-jsonata \ No newline at end of file diff --git a/other/kafka-connect-jsonata/jsonata-drop-tombstone.sh b/other/kafka-connect-jsonata/jsonata-drop-tombstone.sh new file mode 100755 index 0000000000..e7478f5171 --- /dev/null +++ b/other/kafka-connect-jsonata/jsonata-drop-tombstone.sh @@ -0,0 +1,62 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} +playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" + +log "Sending messages to topic filestream" +playground topic produce -t filestream --nb-messages 5 --key 1 << 'EOF' +{ + "fields": [ + { + "doc": "count", + "name": "count", + "type": "long" + }, + { + "doc": "First Name of Customer", + "name": "first_name", + "type": "string" + }, + { + "doc": "Last Name of Customer", + "name": "last_name", + "type": "string" + }, + { + "doc": "Address of Customer", + "name": "address", + "type": "string" + } + ], + "name": "Customer", + "namespace": "com.github.vdesabou", + "type": "record" +} +EOF + +playground topic produce -t filestream --key 1 --tombstone + + +log "Creating FileStream Sink connector" +playground connector create-or-update --connector filestream-sink << EOF +{ + "tasks.max": "1", + "connector.class": "org.apache.kafka.connect.file.FileStreamSinkConnector", + "topics": "filestream", + "file": "/tmp/output.json", + + "transforms": "dropTombstone", + "transforms.dropTombstone.type": "io.yokota.kafka.connect.transform.jsonata.JsonataTransformation", + "transforms.dropTombstone.expr": "value = null ? null : \$" +} +EOF + + +sleep 5 + +log "Verify we have received the data in file" +docker exec connect cat /tmp/output.json diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 667d43c07e..135db55e8e 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -254,7 +254,7 @@ function maybe_create_image() export CONNECT_USER="appuser" if [ `uname -m` = "arm64" ] then - CONNECT_3RDPARTY_INSTALL="if [ ! -f /tmp/done ]; then yum -y install --disablerepo='Confluent*' bind-utils openssl unzip findutils net-tools nc jq which iptables libmnl krb5-workstation krb5-libs vim && yum clean all && rm -rf /var/cache/yum && rpm -i --nosignature https://koji.mbox.centos.org/kojifiles/packages/tcpdump/4.9.3/3.el8/aarch64/tcpdump-4.9.3-3.el8.aarch64.rpm && touch /tmp/done; fi" + CONNECT_3RDPARTY_INSTALL="if [ ! -f /tmp/done ]; then yum -y install --disablerepo='Confluent*' bind-utils openssl unzip findutils net-tools nc jq which iptables libmnl krb5-workstation krb5-libs vim && yum clean all && rm -rf /var/cache/yum && rpm -i --nosignature https://yum.oracle.com/repo/OracleLinux/OL8/appstream/aarch64/getPackage/tcpdump-4.9.3-3.el8.aarch64.rpm && touch /tmp/done; fi" else CONNECT_3RDPARTY_INSTALL="if [ ! -f /tmp/done ]; then curl https://download.rockylinux.org/pub/rocky/8/AppStream/x86_64/kickstart/Packages/t/tcpdump-4.9.3-5.el8.x86_64.rpm -o tcpdump-4.9.3-1.el8.x86_64.rpm && rpm -Uvh tcpdump-4.9.3-1.el8.x86_64.rpm && yum -y install --disablerepo='Confluent*' bind-utils openssl unzip findutils net-tools nc jq which iptables libmnl krb5-workstation krb5-libs vim && yum clean all && rm -rf /var/cache/yum && touch /tmp/done; fi" fi From 64672bf5a4d8a012611a67fa4e563d4950fabc25 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 23 Sep 2024 19:35:56 +0200 Subject: [PATCH 021/659] wip (#10) * separate name for cloud * delete * Add Google Cloud Functions Gen 2 Sink Connector #5869 --- .github/workflows/ci.yml | 2 +- .../fully-managed-gcp-bigtable-sink.sh | 22 ++-- .../README.md | 39 +++++++ .../Screenshot1.png | Bin 0 -> 62139 bytes .../Screenshot2.png | Bin 0 -> 35600 bytes ...anaged-google-cloud-functions-gen2-sink.sh | 98 ++++++++++++++++++ .../stop.sh | 0 .../.gitignore | 0 .../README.md | 4 +- .../Screenshot1.png | Bin .../Screenshot2.png | Bin ...ged-google-cloud-functions-legacy-sink.sh} | 2 + .../stop.sh | 8 ++ .../connect-onprem-to-cloud-avro.sh | 2 + docs/content-template.md | 3 +- 15 files changed, 165 insertions(+), 15 deletions(-) create mode 100644 ccloud/fm-gcp-cloud-functions-gen2-sink/README.md create mode 100644 ccloud/fm-gcp-cloud-functions-gen2-sink/Screenshot1.png create mode 100644 ccloud/fm-gcp-cloud-functions-gen2-sink/Screenshot2.png create mode 100755 ccloud/fm-gcp-cloud-functions-gen2-sink/fully-managed-google-cloud-functions-gen2-sink.sh rename ccloud/{fm-gcp-cloud-functions-sink => fm-gcp-cloud-functions-gen2-sink}/stop.sh (100%) rename ccloud/{fm-gcp-cloud-functions-sink => fm-gcp-cloud-functions-legacy-sink}/.gitignore (100%) rename ccloud/{fm-gcp-cloud-functions-sink => fm-gcp-cloud-functions-legacy-sink}/README.md (80%) rename ccloud/{fm-gcp-cloud-functions-sink => fm-gcp-cloud-functions-legacy-sink}/Screenshot1.png (100%) rename ccloud/{fm-gcp-cloud-functions-sink => fm-gcp-cloud-functions-legacy-sink}/Screenshot2.png (100%) rename ccloud/{fm-gcp-cloud-functions-sink/fully-managed-google-cloud-functions-sink.sh => fm-gcp-cloud-functions-legacy-sink/fully-managed-google-cloud-functions-legacy-sink.sh} (97%) create mode 100755 ccloud/fm-gcp-cloud-functions-legacy-sink/stop.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 389fa5021c..8cdaacd93f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -98,7 +98,7 @@ jobs: "🚀 ccloud/fm-aws-cloudwatch-logs-source ccloud/fm-aws-s3-sink ccloud/fm-aws-s3-source ccloud/fm-azure-event-hubs-source ccloud/fm-azure-service-bus-source ccloud/fm-databricks-delta-lake-sink ccloud/fm-gcp-gcs-sink ccloud/fm-gcp-gcs-source ccloud/fm-aws-dynamodb-sink ccloud/fm-azure-data-lake-storage-gen2-sink ccloud/fm-azure-functions-sink ccloud/fm-azure-synapse-analytics-sink ccloud/fm-azure-cosmosdb-sink ccloud/fm-azure-cosmosdb-source ccloud/fully-managed-datadog-metrics-sink", - "🚀 ccloud/fm-salesforce-cdc-source ccloud/fm-salesforce-platform-events-sink ccloud/fm-salesforce-pushtopics-source ccloud/fm-salesforce-sobject-sink ccloud/fm-snowflake-sink ccloud/fm-gcp-pubsub-source ccloud/fm-gcp-spanner-sink ccloud/fm-aws-cloudwatch-metrics-sink ccloud/fm-gcp-bigquery-legacy-sink ccloud/fm-gcp-bigquery-v2-sink ccloud/fm-github-source ccloud/fm-jira-source ccloud/fm-gcp-cloud-functions-sink ccloud/fm-gcp-bigtable-sink ccloud/fm-pagerduty-sink ccloud/fm-azure-log-analytics-sink", + "🚀 ccloud/fm-salesforce-cdc-source ccloud/fm-salesforce-platform-events-sink ccloud/fm-salesforce-pushtopics-source ccloud/fm-salesforce-sobject-sink ccloud/fm-snowflake-sink ccloud/fm-gcp-pubsub-source ccloud/fm-gcp-spanner-sink ccloud/fm-aws-cloudwatch-metrics-sink ccloud/fm-gcp-bigquery-legacy-sink ccloud/fm-gcp-bigquery-v2-sink ccloud/fm-github-source ccloud/fm-jira-source ccloud/fm-gcp-cloud-functions-legacy-sink ccloud/fm-gcp-cloud-functions-gen2-sink ccloud/fm-gcp-bigtable-sink ccloud/fm-pagerduty-sink ccloud/fm-azure-log-analytics-sink", "🚀 ccloud/fm-aws-kinesis-source ccloud/fm-aws-redshift-sink ccloud/fm-aws-sqs-source ccloud/fm-aws-lambda-sink ccloud/fm-azure-blob-storage-sink ccloud/fm-azure-blob-storage-source ccloud/fm-azure-cognitive-search-sink ccloud/fm-mongodb-atlas-source ccloud/fm-mongodb-atlas-sink ccloud/fm-salesforce-bulkapi-source ccloud/fm-salesforce-bulkapi-2-0-source ccloud/custom-connector-connect-aws-s3-sink", diff --git a/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh b/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh index 6c3b4e7317..941f9c135e 100755 --- a/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh +++ b/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh @@ -32,11 +32,11 @@ cd - bootstrap_ccloud_environment -log "Creating big_query_stats topic" +log "Creating big_query_cloud_stats topic" set +e -playground topic delete --topic big_query_stats +playground topic delete --topic big_query_cloud_stats sleep 3 -playground topic create --topic big_query_stats +playground topic create --topic big_query_cloud_stats set -e log "Doing gsutil authentication" @@ -56,9 +56,9 @@ docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud bigtab function cleanup_cloud_resources { - log "Delete GCP BigTable table kafka_big_query_stats" + log "Delete GCP BigTable table kafka_big_query_cloud_stats" check_if_continue - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE deletetable kafka_big_query_stats + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE deletetable kafka_big_query_cloud_stats log "Delete GCP BigTable instance $GCP_BIGTABLE_INSTANCE" check_if_continue @@ -71,8 +71,8 @@ EOF trap cleanup_cloud_resources EXIT -log "Sending messages to topic big_query_stats" -playground topic produce -t big_query_stats --nb-messages 1 --forced-value '{"users": {"name":"Bob","friends": "1000"}}' --key "simple-key-1" << 'EOF' +log "Sending messages to topic big_query_cloud_stats" +playground topic produce -t big_query_cloud_stats --nb-messages 1 --forced-value '{"users": {"name":"Bob","friends": "1000"}}' --key "simple-key-1" << 'EOF' { "type": "record", "name": "myrecord", @@ -97,10 +97,10 @@ playground topic produce -t big_query_stats --nb-messages 1 --forced-value '{"us ] } EOF -playground topic produce -t big_query_stats --nb-messages 1 --forced-value '{"users": {"name":"Jess","friends": "10000"}}' --key "simple-key-2" << 'EOF' +playground topic produce -t big_query_cloud_stats --nb-messages 1 --forced-value '{"users": {"name":"Jess","friends": "10000"}}' --key "simple-key-2" << 'EOF' {"type":"record","name":"myrecord","fields":[{"name":"users","type":{"name":"columnfamily","type":"record","fields":[{"name":"name","type":"string"},{"name":"friends","type":"string"}]}}]} EOF -playground topic produce -t big_query_stats --nb-messages 1 --forced-value '{"users": {"name":"John","friends": "10000"}}' --key "simple-key-3" << 'EOF' +playground topic produce -t big_query_cloud_stats --nb-messages 1 --forced-value '{"users": {"name":"John","friends": "10000"}}' --key "simple-key-3" << 'EOF' {"type":"record","name":"myrecord","fields":[{"name":"users","type":{"name":"columnfamily","type":"record","fields":[{"name":"name","type":"string"},{"name":"friends","type":"string"}]}}]} EOF @@ -118,7 +118,7 @@ playground connector create-or-update --connector $connector_name << EOF "kafka.auth.mode": "KAFKA_API_KEY", "kafka.api.key": "$CLOUD_KEY", "kafka.api.secret": "$CLOUD_SECRET", - "topics": "big_query_stats", + "topics": "big_query_cloud_stats", "gcp.bigtable.credentials.json" : "$GCP_KEYFILE_CONTENT", "gcp.bigtable.instance.id": "$GCP_BIGTABLE_INSTANCE", "gcp.bigtable.project.id": "$GCP_PROJECT", @@ -144,7 +144,7 @@ then docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cloud-sdk:latest gcloud auth activate-service-account --project ${GCP_PROJECT} --key-file /tmp/keyfile.json log "Verify data is in GCP BigTable" - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_stats > /tmp/result.log 2>&1 + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest cbt -project $GCP_PROJECT -instance $GCP_BIGTABLE_INSTANCE read kafka_big_query_cloud_stats > /tmp/result.log 2>&1 cat /tmp/result.log grep "Bob" /tmp/result.log fi diff --git a/ccloud/fm-gcp-cloud-functions-gen2-sink/README.md b/ccloud/fm-gcp-cloud-functions-gen2-sink/README.md new file mode 100644 index 0000000000..8b4292c547 --- /dev/null +++ b/ccloud/fm-gcp-cloud-functions-gen2-sink/README.md @@ -0,0 +1,39 @@ +# Fully Managed Google Cloud Functions Gen 2 Sink connector + + + +## Objective + +Quickly test [Fully Managed Google Cloud Functions Gen 2 Sink](https://docs.confluent.io/cloud/current/connectors/cc-google-cloud-functions-gen2-sink.html) connector. + + +* Active Google Cloud Platform (GCP) account with authorization to create resources + +## Google Cloud Functions Setup + +* Navigate to the [Google Cloud Console](https://console.cloud.google.com/) + +* Go to the [Cloud Functions](https://console.cloud.google.com/functions) tab. + +![Cloud functions setup](Screenshot1.png) + +* Create a new function. Use the default code that is provided. + +![Cloud functions setup](Screenshot2.png) + +Note down the project id, the region (example `us-central1`), and the function name (example `function-1`) as they will be used later. + +N.B: make sure service account has `Cloud Run Invoker` role. + +## Prerequisites + +See [here](https://kafka-docker-playground.io/#/how-to-use?id=%f0%9f%8c%a4%ef%b8%8f-confluent-cloud-examples) + + +## How to run + +Simply run: + +```bash +$ just use command and search for fully-managed-google-cloud-functions .sh in this folder +``` diff --git a/ccloud/fm-gcp-cloud-functions-gen2-sink/Screenshot1.png b/ccloud/fm-gcp-cloud-functions-gen2-sink/Screenshot1.png new file mode 100644 index 0000000000000000000000000000000000000000..ffa6a199628caf1825d2fa27523f764b8b1005d7 GIT binary patch literal 62139 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 U1q~Hnu7d>$9x@E>5S)+%f%Lr=%#Wg@W?9 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 n>rVd`-~KOv{Eq;#/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh +if [ -z "$GCP_PROJECT" ] +then + logerror "GCP_PROJECT is not set. Export it as environment variable or pass it as argument" + exit 1 +fi + +GCP_FUNCTION_REGION=${1:-europe-west2} +GCP_FUNCTION_FUNCTION=${2:-function-gen2} + +cd ../../ccloud/fm-gcp-cloud-functions-gen2-sink +GCP_KEYFILE="${DIR}/keyfile.json" +if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] +then + logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + exit 1 +else + if [ -f ${GCP_KEYFILE} ] + then + GCP_KEYFILE_CONTENT=$(cat keyfile.json | jq -aRs . | sed 's/^"//' | sed 's/"$//') + else + log "Creating ${GCP_KEYFILE} based on environment variable GCP_KEYFILE_CONTENT" + echo -e "$GCP_KEYFILE_CONTENT" | sed 's/\\"/"/g' > ${GCP_KEYFILE} + fi +fi +cd - + +log "Doing gsutil authentication" +set +e +docker rm -f gcloud-config +set -e +docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cloud-sdk:latest gcloud auth activate-service-account --project ${GCP_PROJECT} --key-file /tmp/keyfile.json + +bootstrap_ccloud_environment + + + +set +e +playground topic delete --topic functions-gen2-messages +sleep 3 +playground topic create --topic functions-gen2-messages +set -e + + +log "Produce test data to the functions-gen2-messages topic in Kafka" +playground topic produce -t functions-gen2-messages --nb-messages 10 --forced-value '{"f1":"value%g"}' << 'EOF' +{ + "type": "record", + "name": "myrecord", + "fields": [ + { + "name": "f1", + "type": "string" + } + ] +} +EOF + +connector_name="GoogleCloudFunctionsGen2Sink_$USER" +set +e +playground connector delete --connector $connector_name > /dev/null 2>&1 +set -e + +log "Creating fully managed connector" +playground connector create-or-update --connector $connector_name << EOF +{ + "connector.class": "GoogleCloudFunctionsGen2Sink", + "name": "$connector_name", + "kafka.auth.mode": "KAFKA_API_KEY", + "kafka.api.key": "$CLOUD_KEY", + "kafka.api.secret": "$CLOUD_SECRET", + "topics": "functions-gen2-messages", + "gcf.name": "$GCP_FUNCTION_FUNCTION", + "gcf.project.id": "$GCP_PROJECT", + "gcf.region.name": "$GCP_FUNCTION_REGION", + "gcp.credentials.json" : "$GCP_KEYFILE_CONTENT", + "input.data.format" : "AVRO", + "tasks.max" : "1" +} +EOF +wait_for_ccloud_connector_up $connector_name 180 + +sleep 10 + + +connectorId=$(get_ccloud_connector_lcc $connector_name) + +log "Verifying topic success-$connectorId" +playground topic consume --topic success-$connectorId --min-expected-messages 10 --timeout 60 + +log "Do you want to delete the fully managed connector $connector_name ?" +check_if_continue + +playground connector delete --connector $connector_name diff --git a/ccloud/fm-gcp-cloud-functions-sink/stop.sh b/ccloud/fm-gcp-cloud-functions-gen2-sink/stop.sh similarity index 100% rename from ccloud/fm-gcp-cloud-functions-sink/stop.sh rename to ccloud/fm-gcp-cloud-functions-gen2-sink/stop.sh diff --git a/ccloud/fm-gcp-cloud-functions-sink/.gitignore b/ccloud/fm-gcp-cloud-functions-legacy-sink/.gitignore similarity index 100% rename from ccloud/fm-gcp-cloud-functions-sink/.gitignore rename to ccloud/fm-gcp-cloud-functions-legacy-sink/.gitignore diff --git a/ccloud/fm-gcp-cloud-functions-sink/README.md b/ccloud/fm-gcp-cloud-functions-legacy-sink/README.md similarity index 80% rename from ccloud/fm-gcp-cloud-functions-sink/README.md rename to ccloud/fm-gcp-cloud-functions-legacy-sink/README.md index 92d8d310f2..bfae5f3cc0 100644 --- a/ccloud/fm-gcp-cloud-functions-sink/README.md +++ b/ccloud/fm-gcp-cloud-functions-legacy-sink/README.md @@ -1,10 +1,10 @@ -# Fully Managed Google Cloud Functions Sink connector +# Fully Managed Google Cloud Functions (Legacy) Sink connector ## Objective -Quickly test [Fully Managed Google Cloud Functions Sink](https://docs.confluent.io/cloud/current/connectors/cc-google-functions-sink.html#google-cloud-functions-sink-connector-for-ccloud) connector. +Quickly test [Fully Managed Google Cloud Functions (Legacy) Sink](https://docs.confluent.io/cloud/current/connectors/cc-google-functions-sink.html) connector. * Active Google Cloud Platform (GCP) account with authorization to create resources diff --git a/ccloud/fm-gcp-cloud-functions-sink/Screenshot1.png b/ccloud/fm-gcp-cloud-functions-legacy-sink/Screenshot1.png similarity index 100% rename from ccloud/fm-gcp-cloud-functions-sink/Screenshot1.png rename to ccloud/fm-gcp-cloud-functions-legacy-sink/Screenshot1.png diff --git a/ccloud/fm-gcp-cloud-functions-sink/Screenshot2.png b/ccloud/fm-gcp-cloud-functions-legacy-sink/Screenshot2.png similarity index 100% rename from ccloud/fm-gcp-cloud-functions-sink/Screenshot2.png rename to ccloud/fm-gcp-cloud-functions-legacy-sink/Screenshot2.png diff --git a/ccloud/fm-gcp-cloud-functions-sink/fully-managed-google-cloud-functions-sink.sh b/ccloud/fm-gcp-cloud-functions-legacy-sink/fully-managed-google-cloud-functions-legacy-sink.sh similarity index 97% rename from ccloud/fm-gcp-cloud-functions-sink/fully-managed-google-cloud-functions-sink.sh rename to ccloud/fm-gcp-cloud-functions-legacy-sink/fully-managed-google-cloud-functions-legacy-sink.sh index c948a7bfce..5df1e6620d 100755 --- a/ccloud/fm-gcp-cloud-functions-sink/fully-managed-google-cloud-functions-sink.sh +++ b/ccloud/fm-gcp-cloud-functions-legacy-sink/fully-managed-google-cloud-functions-legacy-sink.sh @@ -12,6 +12,7 @@ fi GCP_FUNCTION_REGION=${1:-europe-west2} GCP_FUNCTION_FUNCTION=${2:-function-1} +cd ../../ccloud/fm-gcp-cloud-functions-legacy-sink GCP_KEYFILE="${DIR}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then @@ -26,6 +27,7 @@ else echo -e "$GCP_KEYFILE_CONTENT" | sed 's/\\"/"/g' > ${GCP_KEYFILE} fi fi +cd - bootstrap_ccloud_environment diff --git a/ccloud/fm-gcp-cloud-functions-legacy-sink/stop.sh b/ccloud/fm-gcp-cloud-functions-legacy-sink/stop.sh new file mode 100755 index 0000000000..227b07f614 --- /dev/null +++ b/ccloud/fm-gcp-cloud-functions-legacy-sink/stop.sh @@ -0,0 +1,8 @@ +#!/bin/bash + + + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +maybe_delete_ccloud_environment \ No newline at end of file diff --git a/ccloud/replicator/connect-onprem-to-cloud-avro.sh b/ccloud/replicator/connect-onprem-to-cloud-avro.sh index 081bc70949..6a4344887b 100755 --- a/ccloud/replicator/connect-onprem-to-cloud-avro.sh +++ b/ccloud/replicator/connect-onprem-to-cloud-avro.sh @@ -12,6 +12,8 @@ playground start-environment --environment ccloud --docker-compose-override-file log "Creating topic in Confluent Cloud (auto.create.topics.enable=false)" set +e +playground topic delete --topic products-avro +sleep 3 playground topic create --topic products-avro set -e diff --git a/docs/content-template.md b/docs/content-template.md index e7a7475f4e..83f3bbc403 100644 --- a/docs/content-template.md +++ b/docs/content-template.md @@ -218,7 +218,8 @@ - [Google BigQuery (Legacy) Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-gcp-bigquery-legacy-sink) :ccloud/fm-gcp-bigquery-legacy-sink: - [Google BigQuery V2 Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-gcp-bigquery-v2-sink) :ccloud/fm-gcp-bigquery-v2-sink: - [Google Cloud BigTable Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-gcp-bigtable-sink) :ccloud/fm-gcp-bigtable-sink: - - [Google Cloud Functions Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-gcp-cloud-functions-sink) :ccloud/fm-gcp-cloud-functions-sink: + - [Google Cloud Functions Legacy Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-gcp-cloud-functions-legacy-sink) :ccloud/fm-gcp-cloud-functions-legacy-sink: + - [Google Cloud Functions Gen 2 Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-gcp-cloud-functions-gen2-sink) :ccloud/fm-gcp-cloud-functions-gen2-sink: * [Google Cloud Spanner Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-gcp-spanner-sink) :ccloud/fm-gcp-spanner-sink: - [Google Cloud Storage Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-gcp-gcs-sink) :ccloud/fm-gcp-gcs-sink: - [Google Cloud Storage Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-gcp-gcs-source) :ccloud/fm-gcp-gcs-source: From 7688de16430818c0fcc09e5c813c8e35c5b49602 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 26 Sep 2024 12:02:21 +0200 Subject: [PATCH 022/659] update (#12) --- .../connect-jdbc-sybase-sink/sybase-sink.sh | 3 +- scripts/cli/completions.bash | 880 +++++++++--------- scripts/cli/confluent-hub-plugin-list.txt | 1 + scripts/cli/playground | 320 ++++++- scripts/cli/playground.json | 14 +- scripts/cli/playground.yaml | 14 +- scripts/cli/src/bashly.yml | 25 +- .../src/commands/config/check-repo-version.sh | 2 + .../config/container-kill-all-before-run.sh | 2 + .../commands/connector/create-or-update.sh | 2 +- .../src/commands/connector/select-config.sh | 2 +- .../cli/src/commands/connector/show-config.sh | 4 +- .../cli/src/commands/connector/snippets.sh | 2 +- .../cli/src/commands/container/kill-all.sh | 2 +- .../cli/src/commands/get-docker-compose.sh | 1 + scripts/cli/src/commands/repro/bootstrap.sh | 2 +- scripts/cli/src/commands/run.sh | 22 +- scripts/cli/src/commands/start-environment.sh | 14 +- scripts/cli/src/lib/utils_function.sh | 45 +- 19 files changed, 855 insertions(+), 502 deletions(-) create mode 100644 scripts/cli/src/commands/config/check-repo-version.sh create mode 100644 scripts/cli/src/commands/config/container-kill-all-before-run.sh diff --git a/connect/connect-jdbc-sybase-sink/sybase-sink.sh b/connect/connect-jdbc-sybase-sink/sybase-sink.sh index 9a909ee289..89c7e15161 100755 --- a/connect/connect-jdbc-sybase-sink/sybase-sink.sh +++ b/connect/connect-jdbc-sybase-sink/sybase-sink.sh @@ -16,7 +16,8 @@ playground connector create-or-update --connector sybase-sink << EOF "connection.user": "sa", "connection.password": "password", "topics": "orders", - "auto.create": "true" + "auto.create": "true", + "table.name.format": "master.dbo.orders" } EOF diff --git a/scripts/cli/completions.bash b/scripts/cli/completions.bash index 97dc052cb7..0fb603ef25 100644 --- a/scripts/cli/completions.bash +++ b/scripts/cli/completions.bash @@ -48,38 +48,42 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy toggle-writes-service'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") - ;; - *'connector offsets get-offsets-request-status'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tcp-proxy toggle-reads-service'*'--connection-id') + *'tcp-proxy toggle-writes-service'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'tcp-proxy toggle-writes-client'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + *'topic set-schema-compatibility'*'--compatibility') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; *'connector-plugin search-jar'*'--connector-plugin') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; - *'topic set-schema-compatibility'*'--compatibility') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") + *'tcp-proxy toggle-writes-client'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'ec2 sync-repro-folder local-to-ec2'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'tcp-proxy toggle-reads-service'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + ;; + + *'connector open-ccloud-connector-in-browser'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'tcp-proxy toggle-reads-client'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; + *'ec2 sync-repro-folder local-to-ec2'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + ;; + *'connector offsets get-offsets-request-status'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; @@ -88,10 +92,6 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'connector open-ccloud-connector-in-browser'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - *'connector show-config-parameters'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -116,10 +116,6 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'tcp-proxy get-connections'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") - ;; - *'topic produce'*'--key-subject-name-strategy') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") ;; @@ -128,30 +124,34 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'config open-ccloud-connector-in-browser'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h automatically browser")" -- "$cur") + *'tcp-proxy get-connections'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; *'schema set-compatibility'*'--compatibility') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; - *'container set-environment-variables'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'connector create-or-update'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'config open-ccloud-connector-in-browser'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h automatically browser")" -- "$cur") ;; *'topic set-schema-compatibility'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; + *'container set-environment-variables'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + *'debug generate-diagnostics'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'connector create-or-update'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + *'ec2 sync-repro-folder ec2-to-local'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; @@ -160,11 +160,7 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'container get-properties'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'tcp-proxy toggle-accept-connections'*) + *'config container-kill-all-before-run'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -172,11 +168,15 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --env --help --restore-original-values -c -h")" -- "$cur") ;; - *'ec2 sync-repro-folder ec2-to-local'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + *'container get-properties'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'ec2 sync-repro-folder local-to-ec2'*) + *'tcp-proxy toggle-accept-connections'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + + *'ec2 sync-repro-folder ec2-to-local'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; @@ -188,6 +188,10 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; + *'ec2 sync-repro-folder local-to-ec2'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + ;; + *'connector show-config-parameters'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -196,16 +200,16 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'cleanup-cloud-resources'*'--resource') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure ccloud salesforce")" -- "$cur") + *'schema get-compatibility'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; *'schema set-compatibility'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'schema get-compatibility'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'cleanup-cloud-resources'*'--resource') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure ccloud salesforce")" -- "$cur") ;; *'connector create-or-update'*'--level') @@ -220,80 +224,76 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; + *'debug flight-recorder'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + *'connector offsets get'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; + *'topic set-schema-compatibility'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + ;; + *'topic produce'*'--compression-codec') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "gzip snappy lz4 zstd")" -- "$cur") ;; - *'debug flight-recorder'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'tcp-proxy toggle-writes-service'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'topic set-schema-compatibility'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'debug enable-remote-debugging'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'container change-jdk'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy toggle-writes-service'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") - ;; - *'topic get-number-records'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'debug enable-remote-debugging'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'tools install-vscode-extension'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'tcp-proxy toggle-writes-client'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'tcp-proxy break'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + *'debug block-traffic'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'tcp-proxy toggle-reads-service'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'tcp-proxy delay'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + *'topic display-consumer-offsets'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --verbose -h -v")" -- "$cur") ;; - *'debug block-traffic'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'tools install-vscode-extension'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'topic produce'*'--validate-config') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") + *'connector log-level'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'topic display-consumer-offsets'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --verbose -h -v")" -- "$cur") + *'topic produce'*'--validate-config') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") ;; - *'tcp-proxy toggle-writes-client'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'tcp-proxy break'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; *'topic set-schema-compatibility'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --topic --verbose -h -t -v")" -- "$cur") ;; - *'connector log-level'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'tcp-proxy toggle-reads-client'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'tcp-proxy delay'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; *'debug flight-recorder'*'--action') @@ -304,10 +304,6 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") ;; - *'container change-jdk'*'--version') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "8 11 17 21 22")" -- "$cur") - ;; - *'debug enable-remote-debugging'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; @@ -316,23 +312,31 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector-plugin search-jar'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") + *'container change-jdk'*'--version') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "8 11 17 21 22")" -- "$cur") + ;; + + *'connector snippets'*'--converter') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "avro protobuf json-schema json json-schema-enabled string bytearray")" -- "$cur") ;; *'update-version'*'--connector-jar') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") ;; - *'update-version'*'--connector-zip') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") + *'tcp-proxy toggle-reads-client'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'connector snippets'*'--converter') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "avro protobuf json-schema json json-schema-enabled string bytearray")" -- "$cur") + *'connector-plugin search-jar'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; - *'debug generate-diagnostics'*'-c') + *'update-version'*'--connector-zip') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") + ;; + + *'container unpause'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -340,54 +344,46 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'topic produce'*'--compatibility') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") + *'debug generate-diagnostics'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector unpause'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug thread-dump'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'connector create-or-update'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug thread-dump'*'--container') + *'container restart'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector restart'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - *'connector create-or-update'*'-l') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'container unpause'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'container restart'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector unpause'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector-plugin versions'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") + *'topic produce'*'--compatibility') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; - *'connector status'*'--connector') + *'connector restart'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector-plugin search-jar'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--class --connector-plugin --connector-tag --help -c -h")" -- "$cur") - ;; - *'connector delete'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; + *'container resume'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + *'connector resume'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -396,20 +392,24 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") ;; - *'container resume'*'--container') + *'debug java-debug'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector update'*'--connector') + *'connector status'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug java-debug'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector-plugin versions'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; - *'container get-ip-addresses'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'connector update'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'connector-plugin search-jar'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--class --connector-plugin --connector-tag --help -c -h")" -- "$cur") ;; *'container get-properties'*'-c') @@ -420,60 +420,72 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'topic consume'*'--key-subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'connector create-or-update'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level --offsets --package --skip-automatic-connector-config --validate --verbose --wait-for-zero-lag -c -h -l -p -v")" -- "$cur") ;; - *'topic get-number-records'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'container get-ip-addresses'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'get-jmx-metrics'*'--container') + *'container pause'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector log-level'*'--level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") - ;; - *'debug log-level set'*'--level') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'connector create-or-update'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level --offsets --package --skip-automatic-connector-config --validate --verbose --wait-for-zero-lag -c -h -l -p -v")" -- "$cur") + *'get-jmx-metrics'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector pause'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug heap-dump'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'tools read-avro-file'*'--file') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") ;; - *'tcp-proxy close-connection'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'topic consume'*'--key-subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'debug heap-dump'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector log-level'*'--level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'container pause'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic get-number-records'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'container logs'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; + *'tcp-proxy close-connection'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + ;; + + *'connector pause'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'connector stop'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; *'debug tcp-dump'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'ec2 create'*'--instance-type') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "c1.medium c1.xlarge c3.2xlarge c3.4xlarge c3.8xlarge c3.large c3.xlarge c4.2xlarge c4.4xlarge c4.large c4.xlarge m1.large m1.medium m1.small m1.xlarge m2.2xlarge m2.4xlarge m2.xlarge m3.2xlarge m3.large m3.medium m3.xlarge m4.10xlarge m4.2xlarge m4.4xlarge m4.large m4.xlarge t1.micro t2.large t2.medium t2.micro t2.nano t2.small t3.2xlarge")" -- "$cur") + *'connector offsets reset'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'connector-plugin versions'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-plugin --force-refresh --help --last -c -h")" -- "$cur") + ;; + + *'container logs'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'container exec'*'--container') @@ -484,39 +496,39 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'container kill'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'ec2 create'*'--instance-type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "c1.medium c1.xlarge c3.2xlarge c3.4xlarge c3.8xlarge c3.large c3.xlarge c4.2xlarge c4.4xlarge c4.large c4.xlarge m1.large m1.medium m1.small m1.xlarge m2.2xlarge m2.4xlarge m2.xlarge m3.2xlarge m3.large m3.medium m3.xlarge m4.10xlarge m4.2xlarge m4.4xlarge m4.large m4.xlarge t1.micro t2.large t2.medium t2.micro t2.nano t2.small t3.2xlarge")" -- "$cur") ;; - *'connector select-config'*'-c') + *'connector offsets alter'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tcp-proxy get-connections'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'config check-repo-version'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector-plugin versions'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-plugin --force-refresh --help --last -c -h")" -- "$cur") + *'tcp-proxy start'*'--hostname') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'tools read-parquet-file'*'-f') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") ;; - *'connector offsets reset'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container kill'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'repro bootstrap'*'--pipeline') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro --sink-only "$cur")")" -- "$cur") + *'tcp-proxy get-connections'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'connector stop'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'repro bootstrap'*'--pipeline') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro --sink-only "$cur")")" -- "$cur") ;; - *'connector offsets alter'*'-c') + *'connector select-config'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -524,23 +536,15 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") ;; - *'tcp-proxy start'*'--hostname') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'schema register'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") - ;; - - *'topic produce'*'--reference') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + *'topic get-number-records'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") ;; - *'schema get-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") + *'run'*'--cluster-environment') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-environment-list "$cur")")" -- "$cur") ;; - *'config folder_zip_or_jar'*) + *'remove-all-docker-images'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -548,44 +552,40 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'schema set-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --subject --verbose -h -v")" -- "$cur") - ;; - *'container ssh'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'schema set-mode'*'--subject') + *'schema register'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'schema get-mode'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'schema get-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; - *'debug java-debug'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "enable disable")" -- "$cur") + *'schema set-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --subject --verbose -h -v")" -- "$cur") ;; - *'remove-all-docker-images'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'schema get-mode'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'topic get-number-records'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") + *'schema set-mode'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'run'*'--cluster-environment') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-environment-list "$cur")")" -- "$cur") + *'config folder_zip_or_jar'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector offsets get'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'topic produce'*'--reference') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'connector offsets reset'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'debug java-debug'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "enable disable")" -- "$cur") ;; *'schema register'*'--schema') @@ -604,39 +604,39 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--force --help --resource -h")" -- "$cur") ;; - *'tools read-parquet-file'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + *'connector select-config'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") ;; - *'connector show-config'*'-c') + *'connector offsets get'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector select-config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") - ;; - - *'container change-jdk'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'tools read-parquet-file'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'debug java-debug'*'--type') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ssl_all ssl_handshake class_loading kerberos")" -- "$cur") + *'connector offsets reset'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'tools read-avro-file'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") + *'connector show-config'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'schema delete'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'debug flight-recorder'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help -c -h")" -- "$cur") + *'tools read-avro-file'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") ;; - *'debug block-traffic'*'-c') + *'debug java-debug'*'--type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ssl_all ssl_handshake class_loading kerberos")" -- "$cur") + ;; + + *'container change-jdk'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -648,11 +648,23 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'debug log-level set'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'ec2 sync-repro-folder'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h ec2-to-local local-to-ec2")" -- "$cur") ;; - *'connector log-level'*'-l') + *'cleanup-cloud-details'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + + *'schema set-mode'*'--mode') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") + ;; + + *'connector offsets get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + ;; + + *'debug log-level set'*'-l') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; @@ -660,47 +672,51 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'connector log-level'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug flight-recorder'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help -c -h")" -- "$cur") ;; - *'schema set-mode'*'--mode') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") + *'debug block-traffic'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector offsets get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'connector log-level'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'connector show-config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-rest-endpoint --help --verbose -c -h -v")" -- "$cur") + *'connector log-level'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'repro bootstrap'*'--file') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") ;; - *'cleanup-cloud-details'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'connector show-config'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-rest-endpoint --help --verbose -c -h -v")" -- "$cur") ;; - *'ec2 sync-repro-folder'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h ec2-to-local local-to-ec2")" -- "$cur") + *'ec2 delete'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") + ;; + + *'topic consume'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'tools read-avro-file'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'topic produce'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'connector show-lag'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'topic produce'*'--value') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'topic consume'*'--topic') + *'topic produce'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; @@ -708,38 +724,22 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'connector show-lag'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'ec2 delete'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") + *'container change-jdk'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --version -c -h")" -- "$cur") ;; *'container ssh'*'--shell') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'container change-jdk'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --version -c -h")" -- "$cur") + *'connector unpause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'connector open-docs'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") ;; - *'container restart'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'debug thread-dump'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'schema get'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") - ;; - *'update-version'*'--tag') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") ;; @@ -748,58 +748,86 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level -c -h -l")" -- "$cur") ;; - *'debug block-traffic'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --destination --help --port -c -h")" -- "$cur") + *'connector restart'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'run'*'--cluster-region') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-kafka-region-list "$cur")")" -- "$cur") ;; *'ec2 start'*'--instance') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'debug log-level get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --package -h -p")" -- "$cur") + *'topic delete'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + ;; + + *'container restart'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'debug log-level set'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --level --package -h -l -p")" -- "$cur") ;; - *'run'*'--cluster-region') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-kafka-region-list "$cur")")" -- "$cur") + *'debug log-level get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --package -h -p")" -- "$cur") ;; - *'topic delete'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'container unpause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector restart'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug block-traffic'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --destination --help --port -c -h")" -- "$cur") ;; - *'container unpause'*'-c') + *'debug thread-dump'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector unpause'*'-c') + *'schema get'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + ;; + + *'connector resume'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'topic alter'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'connector versions'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'ec2 stop'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'run'*'--connector-jar') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") ;; - *'ec2 open'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'run'*'--cluster-cloud') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure")" -- "$cur") + ;; + + *'connector delete'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'debug java-debug'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'connector snippets'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--converter --dlq --help -h")" -- "$cur") ;; + *'connector show-lag'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --interval --max-wait --verbose -c -h -v")" -- "$cur") + ;; + + *'repro import'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") + ;; + *'connector status'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -808,123 +836,135 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --ignore-current-versions -h")" -- "$cur") ;; - *'get-docker-compose'*) + *'container kill-all'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'repro import'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") + *'topic alter'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector show-lag'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --interval --max-wait --verbose -c -h -v")" -- "$cur") + *'run'*'--connector-zip') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") ;; - *'connector versions'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'ec2 open'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'connector delete'*'-c') + *'ec2 stop'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + ;; + + *'connector update'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container kill-all'*) + *'get-docker-compose'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector resume'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'topic produce'*'--key') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; *'container resume'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic produce'*'--key') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + *'container pause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'run'*'--connector-zip') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") + *'connector offsets'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter get get-offsets-request-status reset")" -- "$cur") ;; - *'debug java-debug'*'-c') + *'run'*'--cluster-name') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") + ;; + + *'get-jmx-metrics'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector update'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container unpause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'run'*'--cluster-cloud') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure")" -- "$cur") + *'run'*'--cluster-type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "basic standard dedicated")" -- "$cur") ;; - *'run'*'--connector-jar') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") + *'connector plugins'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help --verbose -h -v")" -- "$cur") ;; - *'run'*'--cluster-name') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") + *'connector pause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'connector restart'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; *'debug heap-dump'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector offsets'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter get get-offsets-request-status reset")" -- "$cur") + *'connector unpause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'repro bootstrap'*'-p') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") + *'debug thread-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'repro bootstrap'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") + *'container restart'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'connector plugins'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help --verbose -h -v")" -- "$cur") + *'repro bootstrap'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") ;; - *'connector pause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'repro bootstrap'*'-p') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") ;; - *'connector restart'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'run'*'--environment') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") ;; - *'container pause'*'-c') + *'container exec'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container unpause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'connector delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'connector unpause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'connector update'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") ;; - *'container restart'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'config clipboard'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'get-jmx-metrics'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector resume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'run'*'--cluster-type') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "basic standard dedicated")" -- "$cur") + *'connector stop'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug thread-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'debug tcp-dump'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container logs'*'-c') + *'container kill'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -932,56 +972,48 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help --type -c -h")" -- "$cur") ;; - *'connector-plugin'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h search-jar versions")" -- "$cur") - ;; - - *'container resume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") - ;; - *'topic describe'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'container logs'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug tcp-dump'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector status'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'config clipboard'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'container resume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'connector update'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") + *'connector-plugin'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h search-jar versions")" -- "$cur") ;; - *'connector stop'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug heap-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") ;; - *'connector resume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'schema get-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; - *'run'*'--environment') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") + *'container pause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'container kill'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic consume'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector status'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'schema set-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") ;; - *'container exec'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'repro bootstrap'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--custom-smt --description --file --help --pipeline -d -f -h")" -- "$cur") ;; *'container ssh'*'-s') @@ -992,112 +1024,92 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") ;; - *'get-jmx-metrics'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --domain --help --open -c -d -h -o")" -- "$cur") - ;; - - *'debug log-level'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h get set")" -- "$cur") - ;; - - *'topic produce'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") - ;; - *'tcp-proxy start'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --delay-service-response --help --hostname --port --service-response-corrupt --skip-automatic-connector-config --throttle-service-response -h")" -- "$cur") ;; - *'tcp-proxy delay'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") + *'get-jmx-metrics'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --domain --help --open -c -d -h -o")" -- "$cur") ;; *'connector pause'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'repro bootstrap'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--custom-smt --description --file --help --pipeline -d -f -h")" -- "$cur") - ;; - - *'topic consume'*'-t') + *'topic produce'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'container pause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'container ssh'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'schema register'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --schema --subject --verbose -h -v")" -- "$cur") ;; - *'container ssh'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'tcp-proxy delay'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") ;; - *'debug heap-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") + *'debug log-level'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h get set")" -- "$cur") ;; - *'schema get-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") + *'update-version'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-jar --connector-tag --connector-zip --help --tag -h")" -- "$cur") ;; - *'schema set-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") + *'container logs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") ;; - *'connector logs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") + *'repro import'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") ;; - *'update-version'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-jar --connector-tag --connector-zip --help --tag -h")" -- "$cur") + *'container exec'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--command --container --help --root --shell -c -h")" -- "$cur") ;; - *'topic describe'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") + *'debug tcp-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --duration --help --port -c -h")" -- "$cur") ;; *'connector stop'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'container exec'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--command --container --help --root --shell -c -h")" -- "$cur") + *'topic describe'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") ;; - *'container logs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") + *'connector logs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") ;; - *'topic delete'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'container kill'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'repro import'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") + *'topic delete'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'container kill'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'schema delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --permanent --subject --verbose --version -h -v")" -- "$cur") ;; - *'debug tcp-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --duration --help --port -c -h")" -- "$cur") + *'config editor'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'topic produce'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") ;; - *'topic alter'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") - ;; - - *'schema delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --permanent --subject --verbose --version -h -v")" -- "$cur") + *'--output-level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") ;; *'debug testssl'*) @@ -1112,16 +1124,16 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'config editor'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'container ssh'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") ;; - *'--output-level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") + *'topic alter'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + ;; + + *'repro export'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help -h")" -- "$cur") ;; *'ec2 delete'*'-i') @@ -1132,34 +1144,34 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'topic delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --skip-delete-schema --topic --verbose -h -t -v")" -- "$cur") - ;; - *'topic create'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --nb-partitions --topic --verbose -h -t -v")" -- "$cur") ;; - *'repro export'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help -h")" -- "$cur") + *'topic delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --skip-delete-schema --topic --verbose -h -t -v")" -- "$cur") ;; *'switch-back'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'ec2 start'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") - ;; - *'topic alter'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") ;; + *'ec2 start'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + ;; + *'topic list'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; + *'open'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") + ;; + *'ec2 stop'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; @@ -1168,34 +1180,18 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance-type --size --suffix -h")" -- "$cur") ;; - *'schema get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") - ;; - *'ec2 delete'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'open'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") + *'schema get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") ;; *'ec2 open'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'container'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h change-jdk exec get-ip-addresses get-properties kill kill-all logs pause recreate restart resume set-environment-variables ssh unpause")" -- "$cur") - ;; - - *'ec2 start'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") - ;; - - *'run'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") - ;; - *'tcp-proxy'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h break close-all-connection-with-error close-connection delay get-connections start toggle-accept-connections toggle-reads-client toggle-reads-service toggle-writes-client toggle-writes-service")" -- "$cur") ;; @@ -1204,18 +1200,30 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create-or-update delete log-level logs offsets open-ccloud-connector-in-browser open-docs pause plugins restart resume select-config show-config show-config-parameters show-lag snippets status stop unpause update versions")" -- "$cur") ;; + *'container'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h change-jdk exec get-ip-addresses get-properties kill kill-all logs pause recreate restart resume set-environment-variables ssh unpause")" -- "$cur") + ;; + *'open-docs'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") ;; - *'run'*'--tag') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") + *'ec2 start'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + ;; + + *'run'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") ;; *'ec2 open'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--disable-sync-repro-folder --help --instance -h -i")" -- "$cur") ;; + *'run'*'--tag') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") + ;; + *'ec2 list'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -1228,16 +1236,8 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'re-run'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h clipboard editor folder_zip_or_jar open-ccloud-connector-in-browser")" -- "$cur") - ;; - - *'schema'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h delete get get-compatibility get-mode register set-compatibility set-mode")" -- "$cur") + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h check-repo-version clipboard container-kill-all-before-run editor folder_zip_or_jar open-ccloud-connector-in-browser")" -- "$cur") ;; *'open'*'-f') @@ -1248,8 +1248,16 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'topic'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter consume create delete describe display-consumer-offsets get-number-records list produce set-schema-compatibility")" -- "$cur") + *'re-run'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + + *'schema'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h delete get get-compatibility get-mode register set-compatibility set-mode")" -- "$cur") + ;; + + *'tools'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h install-vscode-extension read-avro-file read-parquet-file")" -- "$cur") ;; *'run'*'-f') @@ -1260,22 +1268,22 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h block-traffic enable-remote-debugging flight-recorder generate-diagnostics heap-dump java-debug log-level tcp-dump testssl thread-dump")" -- "$cur") ;; - *'tools'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h install-vscode-extension read-avro-file read-parquet-file")" -- "$cur") - ;; - *'repro'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h bootstrap export import")" -- "$cur") ;; - *'open'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + *'topic'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter consume create delete describe display-consumer-offsets get-number-records list produce set-schema-compatibility")" -- "$cur") ;; *'stop'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; + *'open'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + ;; + *'help'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index 1f1ea71301..6b9fb060ae 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -146,6 +146,7 @@ jcustenborder/kafka-connect-redis jcustenborder/kafka-connect-spooldir jcustenborder/kafka-connect-transform-common jcustenborder/kafka-connect-twitter +jrndio/jr-source-connector juxt/kafka-connect-crux kaliy/kafka-connect-rss kategmbh/kafka-adapter-for-sap-process-orchestration diff --git a/scripts/cli/playground b/scripts/cli/playground index da51e1959a..03f270a3bf 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -1129,6 +1129,8 @@ playground_config_usage() { printf " %s 📂 list of folders where to search for zip or jar\n" "$(green "folder_zip_or_jar") " printf " %s copy to clipboard connector config (only working on MacOS)\n" "$(green "clipboard") " printf " %s when running a fully managed connector example, it opens the connector in browser\n" "$(green "open-ccloud-connector-in-browser")" + printf " %s when running an example, always call playground container kill-all first. If not set, it will call playground stop instead.\n" "$(green "container-kill-all-before-run") " + printf " %s when running an example, always check if repo version is older than 3 days, if disabled, it will skip this check.\n" "$(green "check-repo-version") " echo # :command.long_usage @@ -1452,11 +1454,93 @@ playground_config_open_ccloud_connector_in_browser_browser_usage() { fi } +# :command.usage +playground_config_container_kill_all_before_run_usage() { + if [[ -n $long_usage ]]; then + printf "playground config container-kill-all-before-run\n\n" + printf " when running an example, always call playground container kill-all first. If\n not set, it will call playground stop instead.\n\n" + else + printf "playground config container-kill-all-before-run - when running an example, always call playground container kill-all first. If not set, it will call playground stop instead.\n\n" + fi + + printf "%s\n" "$(bold "== Usage ==")" + printf " playground config container-kill-all-before-run [ENABLED]\n" + printf " playground config container-kill-all-before-run --help | -h\n" + echo + + # :command.long_usage + if [[ -n "$long_usage" ]]; then + printf "%s\n" "$(bold "== Options ==")" + + # :command.usage_fixed_flags + printf " %s\n" "$(magenta "--help, -h")" + printf " Show this help\n" + echo + + # :command.usage_args + printf "%s\n" "$(bold "== Arguments ==")" + + # :argument.usage + printf " %s\n" "$(blue "ENABLED")" + printf "\n" + printf " %s\n" "Default: true" + echo + + # :command.usage_examples + printf "%s\n" "$(bold "Examples")" + printf " playground config container-kill-all-before-run false\n" + printf " playground config container-kill-all-before-run true\n" + echo + + fi +} + +# :command.usage +playground_config_check_repo_version_usage() { + if [[ -n $long_usage ]]; then + printf "playground config check-repo-version\n\n" + printf " when running an example, always check if repo version is older than 3 days, if\n disabled, it will skip this check.\n\n" + else + printf "playground config check-repo-version - when running an example, always check if repo version is older than 3 days, if disabled, it will skip this check.\n\n" + fi + + printf "%s\n" "$(bold "== Usage ==")" + printf " playground config check-repo-version [ENABLED]\n" + printf " playground config check-repo-version --help | -h\n" + echo + + # :command.long_usage + if [[ -n "$long_usage" ]]; then + printf "%s\n" "$(bold "== Options ==")" + + # :command.usage_fixed_flags + printf " %s\n" "$(magenta "--help, -h")" + printf " Show this help\n" + echo + + # :command.usage_args + printf "%s\n" "$(bold "== Arguments ==")" + + # :argument.usage + printf " %s\n" "$(blue "ENABLED")" + printf "\n" + printf " %s\n" "Default: true" + echo + + # :command.usage_examples + printf "%s\n" "$(bold "Examples")" + printf " playground config check-repo-version false\n" + printf " playground config check-repo-version true\n" + echo + + fi +} + # :command.usage playground_run_usage() { if [[ -n $long_usage ]]; then printf "playground run\n\n" - printf " 🕹️ Run any example !\n \n 🔥 It start an interactive mode where you'll be fully guided !\n \n \n ⛅ When running Confluent Cloud (ccloud) example:\n \n All you have to do is to be already logged in with confluent CLI.\n \n By default, a new Confluent Cloud environment with a Cluster will be\n created.\n \n You can configure the new cluster by setting:\n \n --cluster-type (or CLUSTER_TYPE environment variable): The type of cluster\n (possible values: basic, standard and dedicated, default basic)\n --cluster-cloud (or CLUSTER_CLOUD environment variable): The Cloud provider\n (possible values: aws, gcp and azure, default aws)\n --cluster-region (or CLUSTER_REGION environment variable): The Cloud region\n (use confluent kafka region list to get the list, default eu-west-2 for aws,\n westeurope for azure and europe-west2 for gcp)\n --cluster-environment (or ENVIRONMENT environment variable) (optional): The\n environment id where want your new cluster (example: txxxxx)\n \n In case you want to use your own existing cluster, you need to setup, in\n addition to previous ones:\n \n --cluster-name (or CLUSTER_NAME environment variable): The cluster name\n --cluster-creds (or CLUSTER_CREDS environment variable): The Kafka api key\n and secret to use, it should be separated with colon (example:\n :)\n --cluster-schema-registry-creds (or SCHEMA_REGISTRY_CREDS environment\n variable) (optional, if not set, new one will be created): The Schema Registry\n api key and secret to use, it should be separated with colon (example:\n :)\n \n ❗ this command will kill all containers using playground container kill-all\n\n" + printf " 🕹️ Run any example !\n \n 🔥 It start an interactive mode where you'll be fully guided !\n \n \n ⛅ When running Confluent Cloud (ccloud) example:\n \n All you have to do is to be already logged in with confluent CLI.\n \n By default, a new Confluent Cloud environment with a Cluster will be\n created.\n \n You can configure the new cluster by setting:\n \n --cluster-type (or CLUSTER_TYPE environment variable): The type of cluster\n (possible values: basic, standard and dedicated, default basic)\n --cluster-cloud (or CLUSTER_CLOUD environment variable): The Cloud provider\n (possible values: aws, gcp and azure, default aws)\n --cluster-region (or CLUSTER_REGION environment variable): The Cloud region\n (use confluent kafka region list to get the list, default eu-west-2 for aws,\n westeurope for azure and europe-west2 for gcp)\n --cluster-environment (or ENVIRONMENT environment variable) (optional): The\n environment id where want your new cluster (example: txxxxx)\n \n In case you want to use your own existing cluster, you need to setup, in\n addition to previous ones:\n \n --cluster-name (or CLUSTER_NAME environment variable): The cluster name\n --cluster-creds (or CLUSTER_CREDS environment variable): The Kafka api key\n and secret to use, it should be separated with colon (example:\n :)\n --cluster-schema-registry-creds (or SCHEMA_REGISTRY_CREDS environment\n variable) (optional, if not set, new one will be created): The Schema Registry\n api key and secret to use, it should be separated with colon (example:\n :)\n \n ❗ this command will kill all containers using \"playground container kill-all\",\n you can disable this by running \"playground config\n container-kill-all-before-run false\"\n\n" else printf "playground run - 🕹️ Run any example !\n\n" fi @@ -8196,7 +8280,7 @@ function maybe_create_image() export CONNECT_USER="appuser" if [ `uname -m` = "arm64" ] then - CONNECT_3RDPARTY_INSTALL="if [ ! -f /tmp/done ]; then yum -y install --disablerepo='Confluent*' bind-utils openssl unzip findutils net-tools nc jq which iptables libmnl krb5-workstation krb5-libs vim && yum clean all && rm -rf /var/cache/yum && rpm -i --nosignature https://koji.mbox.centos.org/kojifiles/packages/tcpdump/4.9.3/3.el8/aarch64/tcpdump-4.9.3-3.el8.aarch64.rpm && touch /tmp/done; fi" + CONNECT_3RDPARTY_INSTALL="if [ ! -f /tmp/done ]; then yum -y install --disablerepo='Confluent*' bind-utils openssl unzip findutils net-tools nc jq which iptables libmnl krb5-workstation krb5-libs vim && yum clean all && rm -rf /var/cache/yum && rpm -i --nosignature https://yum.oracle.com/repo/OracleLinux/OL8/appstream/aarch64/getPackage/tcpdump-4.9.3-3.el8.aarch64.rpm && touch /tmp/done; fi" else CONNECT_3RDPARTY_INSTALL="if [ ! -f /tmp/done ]; then curl https://download.rockylinux.org/pub/rocky/8/AppStream/x86_64/kickstart/Packages/t/tcpdump-4.9.3-5.el8.x86_64.rpm -o tcpdump-4.9.3-1.el8.x86_64.rpm && rpm -Uvh tcpdump-4.9.3-1.el8.x86_64.rpm && yum -y install --disablerepo='Confluent*' bind-utils openssl unzip findutils net-tools nc jq which iptables libmnl krb5-workstation krb5-libs vim && yum clean all && rm -rf /var/cache/yum && touch /tmp/done; fi" fi @@ -8386,29 +8470,38 @@ function check_bash_version() { } function check_playground_version() { - set +e - X=3 - git fetch - latest_commit_date=$(git log -1 --format=%cd --date=short) - remote_commit_date=$(git log -1 --format=%cd --date=short origin/master) - - if [[ "$OSTYPE" == "darwin"* ]] + check_repo_version=$(playground config get check-repo-version) + if [ "$check_repo_version" == "" ] then - latest_commit_date_seconds=$(date -j -f "%Y-%m-%d" "$latest_commit_date" +%s) - remote_commit_date_seconds=$(date -j -f "%Y-%m-%d" "$remote_commit_date" +%s) - else - latest_commit_date_seconds=$(date -d "$latest_commit_date" +%s) - remote_commit_date_seconds=$(date -d "$remote_commit_date" +%s) + playground config set check-repo-version true fi - difference=$(( (remote_commit_date_seconds - latest_commit_date_seconds) / (60*60*24) )) - - if [ $difference -gt $X ] + if [ "$check_repo_version" == "true" ] || [ "$check_repo_version" == "" ] then - logwarn "🥶 The current repo version is older than $X days ($difference days), please refresh your version using git pull !" - check_if_continue + set +e + X=3 + git fetch + latest_commit_date=$(git log -1 --format=%cd --date=short) + remote_commit_date=$(git log -1 --format=%cd --date=short origin/master) + + if [[ "$OSTYPE" == "darwin"* ]] + then + latest_commit_date_seconds=$(date -j -f "%Y-%m-%d" "$latest_commit_date" +%s) + remote_commit_date_seconds=$(date -j -f "%Y-%m-%d" "$remote_commit_date" +%s) + else + latest_commit_date_seconds=$(date -d "$latest_commit_date" +%s) + remote_commit_date_seconds=$(date -d "$remote_commit_date" +%s) + fi + + difference=$(( (remote_commit_date_seconds - latest_commit_date_seconds) / (60*60*24) )) + + if [ $difference -gt $X ] + then + logwarn "🥶 The current repo version is older than $X days ($difference days), please refresh your version using git pull ! (disable with 'playground config check-repo-version false')" + check_if_continue + fi + set -e fi - set -e } function set_profiles() { @@ -13334,6 +13427,20 @@ playground_config_open_ccloud_connector_in_browser_browser_command() { playground config set open-ccloud-connector-in-browser.browser "${args[browser]}" } +# :command.function +playground_config_container_kill_all_before_run_command() { + # src/commands/config/container-kill-all-before-run.sh + log "📋 configuring container-kill-all-before-run with ${args[enabled]}" + playground config set container-kill-all-before-run "${args[enabled]}" +} + +# :command.function +playground_config_check_repo_version_command() { + # src/commands/config/check-repo-version.sh + log "📋 configuring check-repo-version with ${args[enabled]}" + playground config set check-repo-version "${args[enabled]}" +} + # :command.function playground_run_command() { # src/commands/run.sh @@ -13410,6 +13517,22 @@ playground_run_command() { verify_installed "confluent" fi + set +e + container_kill_all_before_run=$(playground config get container-kill-all-before-run) + if [ "$container_kill_all_before_run" == "" ] + then + playground config set container-kill-all-before-run true + fi + + if [ "$container_kill_all_before_run" == "true" ] || [ "$container_kill_all_before_run" == "" ] + then + log "💀 kill all docker containers (disable with 'playground config container-kill-all-before-run false')" + playground container kill-all + else + playground stop + fi + set -e + playground state set run.test_file "$test_file" test_file_directory="$(dirname "${test_file}")" filename=$(basename -- "$test_file") @@ -14792,9 +14915,7 @@ playground_run_command() { log "🚀 Running example without any flags" fi fi - set +e - playground container kill-all - set -e + playground state set run.connector_type "$(get_connector_type | tr -d '\n')" playground state set run.test_file "$test_file" echo "" >> "$root_folder/playground-run-history" @@ -14811,7 +14932,7 @@ playground_run_command() { if [ "$clipboard" == "true" ] || [ "$clipboard" == "" ] then echo "playground run -f $test_file $flag_list" | pbcopy - log "📋 command to run again example has been copied to the clipboard (disable with 'playground config set clipboard false')" + log "📋 command to run again example has been copied to the clipboard (disable with 'playground config clipboard false')" fi fi @@ -14965,7 +15086,19 @@ playground_start_environment_command() { test_file_directory="$(dirname "${test_file}")" set +e - playground container kill-all + container_kill_all_before_run=$(playground config get container-kill-all-before-run) + if [ "$container_kill_all_before_run" == "" ] + then + playground config set container-kill-all-before-run true + fi + + if [ "$container_kill_all_before_run" == "true" ] || [ "$container_kill_all_before_run" == "" ] + then + log "💀 kill all docker containers (disable with 'playground config container-kill-all-before-run false')" + playground container kill-all + else + playground stop + fi set -e if [[ -n "$wait_for_control_center" ]] @@ -17412,7 +17545,7 @@ EOF if [ "$clipboard" == "true" ] || [ "$clipboard" == "" ] then echo "playground run -f $repro_dir/$repro_test_filename"| pbcopy - log "📋 command to run generated example has been copied to the clipboard (disable with 'playground config set clipboard false')" + log "📋 command to run generated example has been copied to the clipboard (disable with 'playground config clipboard false')" fi fi @@ -17463,6 +17596,7 @@ playground_get_docker_compose_command() { fi echo "$docker_command" > /tmp/tmp sed -e "s|up -d|config|g" \ + -e "s|--quiet-pull||g" \ /tmp/tmp > /tmp/playground-command-config bash /tmp/playground-command-config @@ -19140,7 +19274,7 @@ playground_container_get_ip_addresses_command() { # :command.function playground_container_kill_all_command() { # src/commands/container/kill-all.sh - log "💀 Kill all docker containers" + log "💀 kill all docker containers" docker rm -f $(docker ps -qa) > /dev/null 2>&1 } @@ -23243,7 +23377,7 @@ playground_connector_show_config_command() { echo "EOF" >> $tmp_dir/tmp cat $tmp_dir/tmp | pbcopy - log "📋 $connector_type connector config has been copied to the clipboard (disable with 'playground config set clipboard false')" + log "📋 $connector_type connector config has been copied to the clipboard (disable with 'playground config clipboard false')" fi fi else @@ -23289,7 +23423,7 @@ playground_connector_show_config_command() { echo "EOF" >> $tmp_dir/tmp cat $tmp_dir/tmp | pbcopy - log "📋 $connector_type connector config has been copied to the clipboard (disable with 'playground config set clipboard false')" + log "📋 $connector_type connector config has been copied to the clipboard (disable with 'playground config clipboard false')" fi fi fi @@ -23614,7 +23748,7 @@ playground_connector_select_config_command() { echo "$res" > $tmp_dir/tmp cat $tmp_dir/tmp | pbcopy - log "📋 config has been copied to the clipboard (disable with 'playground config set clipboard false')" + log "📋 config has been copied to the clipboard (disable with 'playground config clipboard false')" fi fi done @@ -23788,7 +23922,7 @@ playground_connector_snippets_command() { if [ "$clipboard" == "true" ] || [ "$clipboard" == "" ] then cat $clipboard_file | pbcopy - log "📋 config has been copied to the clipboard (disable with 'playground config set clipboard false')" + log "📋 config has been copied to the clipboard (disable with 'playground config clipboard false')" fi fi fi @@ -24270,7 +24404,7 @@ playground_connector_create_or_update_command() { echo "EOF" >> $tmp_dir_clipboard/tmp cat $tmp_dir_clipboard/tmp | pbcopy - log "📋 $connector_type connector config has been copied to the clipboard (disable with 'playground config set clipboard false')" + log "📋 $connector_type connector config has been copied to the clipboard (disable with 'playground config clipboard false')" fi fi fi @@ -27310,6 +27444,20 @@ playground_config_parse_requirements() { shift $# ;; + container-kill-all-before-run) + action="container-kill-all-before-run" + shift + playground_config_container_kill_all_before_run_parse_requirements "$@" + shift $# + ;; + + check-repo-version) + action="check-repo-version" + shift + playground_config_check_repo_version_parse_requirements "$@" + shift $# + ;; + # :command.command_fallback "") playground_config_usage >&2 @@ -27903,6 +28051,112 @@ playground_config_open_ccloud_connector_in_browser_browser_parse_requirements() } +# :command.parse_requirements +playground_config_container_kill_all_before_run_parse_requirements() { + # :command.fixed_flags_filter + while [[ $# -gt 0 ]]; do + case "${1:-}" in + --help | -h) + long_usage=yes + playground_config_container_kill_all_before_run_usage + exit + ;; + + *) + break + ;; + + esac + done + + # :command.command_filter + action="config container-kill-all-before-run" + + # :command.parse_requirements_while + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; + + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + # :argument.case + if [[ -z ${args['enabled']+x} ]]; then + args['enabled']=$1 + shift + else + printf "invalid argument: %s\n" "$key" >&2 + exit 1 + fi + + ;; + + esac + done + + # :command.default_assignments + [[ -n ${args['enabled']:-} ]] || args['enabled']="true" + +} + +# :command.parse_requirements +playground_config_check_repo_version_parse_requirements() { + # :command.fixed_flags_filter + while [[ $# -gt 0 ]]; do + case "${1:-}" in + --help | -h) + long_usage=yes + playground_config_check_repo_version_usage + exit + ;; + + *) + break + ;; + + esac + done + + # :command.command_filter + action="config check-repo-version" + + # :command.parse_requirements_while + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; + + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + # :argument.case + if [[ -z ${args['enabled']+x} ]]; then + args['enabled']=$1 + shift + else + printf "invalid argument: %s\n" "$key" >&2 + exit 1 + fi + + ;; + + esac + done + + # :command.default_assignments + [[ -n ${args['enabled']:-} ]] || args['enabled']="true" + +} + # :command.parse_requirements playground_run_parse_requirements() { # :command.fixed_flags_filter @@ -38632,6 +38886,8 @@ run() { "config open-ccloud-connector-in-browser") playground_config_open_ccloud_connector_in_browser_command ;; "config open-ccloud-connector-in-browser automatically") playground_config_open_ccloud_connector_in_browser_automatically_command ;; "config open-ccloud-connector-in-browser browser") playground_config_open_ccloud_connector_in_browser_browser_command ;; + "config container-kill-all-before-run") playground_config_container_kill_all_before_run_command ;; + "config check-repo-version") playground_config_check_repo_version_command ;; "run") playground_run_command ;; "re-run") playground_re_run_command ;; "history") playground_history_command ;; diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index 102ae3bb9b..e894900820 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -48,6 +48,18 @@ "description": "when running a fully managed connector example, it opens the connector in browser\n \n", "usage": "playground config open-ccloud-connector-in-browser COMMAND", "options": [] + }, + { + "name": "container-kill-all-before-run", + "description": "when running an example, always call playground container kill-all first. If not set, it will call playground stop instead.\n \n", + "usage": "playground config container-kill-all-before-run [ENABLED]", + "options": [] + }, + { + "name": "check-repo-version", + "description": "when running an example, always check if repo version is older than 3 days, if disabled, it will skip this check.\n \n", + "usage": "playground config check-repo-version [ENABLED]", + "options": [] } ] }, @@ -73,7 +85,7 @@ }, { "name": "run", - "description": "🕹️ Run any example !\n\n🔥 It start an interactive mode where you'll be fully guided !\n\n\n⛅ When running Confluent Cloud (ccloud) example:\n\n All you have to do is to be already logged in with confluent CLI.\n\n By default, a new Confluent Cloud environment with a Cluster will be created.\n\n You can configure the new cluster by setting:\n\n --cluster-type (or CLUSTER_TYPE environment variable): The type of cluster (possible values: basic, standard and dedicated, default basic)\n --cluster-cloud (or CLUSTER_CLOUD environment variable): The Cloud provider (possible values: aws, gcp and azure, default aws)\n --cluster-region (or CLUSTER_REGION environment variable): The Cloud region (use confluent kafka region list to get the list, default eu-west-2 for aws, westeurope for azure and europe-west2 for gcp)\n --cluster-environment (or ENVIRONMENT environment variable) (optional): The environment id where want your new cluster (example: txxxxx) \n\n In case you want to use your own existing cluster, you need to setup, in addition to previous ones:\n\n --cluster-name (or CLUSTER_NAME environment variable): The cluster name\n --cluster-creds (or CLUSTER_CREDS environment variable): The Kafka api key and secret to use, it should be separated with colon (example: :)\n --cluster-schema-registry-creds (or SCHEMA_REGISTRY_CREDS environment variable) (optional, if not set, new one will be created): The Schema Registry api key and secret to use, it should be separated with colon (example: :)\n\n❗ this command will kill all containers using playground container kill-all\n", + "description": "🕹️ Run any example !\n\n🔥 It start an interactive mode where you'll be fully guided !\n\n\n⛅ When running Confluent Cloud (ccloud) example:\n\n All you have to do is to be already logged in with confluent CLI.\n\n By default, a new Confluent Cloud environment with a Cluster will be created.\n\n You can configure the new cluster by setting:\n\n --cluster-type (or CLUSTER_TYPE environment variable): The type of cluster (possible values: basic, standard and dedicated, default basic)\n --cluster-cloud (or CLUSTER_CLOUD environment variable): The Cloud provider (possible values: aws, gcp and azure, default aws)\n --cluster-region (or CLUSTER_REGION environment variable): The Cloud region (use confluent kafka region list to get the list, default eu-west-2 for aws, westeurope for azure and europe-west2 for gcp)\n --cluster-environment (or ENVIRONMENT environment variable) (optional): The environment id where want your new cluster (example: txxxxx) \n\n In case you want to use your own existing cluster, you need to setup, in addition to previous ones:\n\n --cluster-name (or CLUSTER_NAME environment variable): The cluster name\n --cluster-creds (or CLUSTER_CREDS environment variable): The Kafka api key and secret to use, it should be separated with colon (example: :)\n --cluster-schema-registry-creds (or SCHEMA_REGISTRY_CREDS environment variable) (optional, if not set, new one will be created): The Schema Registry api key and secret to use, it should be separated with colon (example: :)\n\n❗ this command will kill all containers using \"playground container kill-all\", you can disable this by running \"playground config container-kill-all-before-run false\"\n", "usage": "playground run [OPTIONS]", "options": [ { diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index f678fdac76..a8ed108bc2 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -49,6 +49,18 @@ subcommands: usage: playground config open-ccloud-connector-in-browser COMMAND options: [] + - name: container-kill-all-before-run + description: | + when running an example, always call playground container kill-all first. If not set, it will call playground stop instead. + + usage: playground config container-kill-all-before-run [ENABLED] + options: [] + - name: check-repo-version + description: | + when running an example, always check if repo version is older than 3 days, if disabled, it will skip this check. + + usage: playground config check-repo-version [ENABLED] + options: [] - name: open-ccloud-connector-in-browser description: | when running a fully managed connector example, it opens the connector in browser @@ -92,7 +104,7 @@ subcommands: --cluster-creds (or CLUSTER_CREDS environment variable): The Kafka api key and secret to use, it should be separated with colon (example: :) --cluster-schema-registry-creds (or SCHEMA_REGISTRY_CREDS environment variable) (optional, if not set, new one will be created): The Schema Registry api key and secret to use, it should be separated with colon (example: :) - ❗ this command will kill all containers using playground container kill-all + ❗ this command will kill all containers using "playground container kill-all", you can disable this by running "playground config container-kill-all-before-run false" usage: playground run [OPTIONS] options: - names: diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index cb8d03c030..c8a5ebfbc8 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -382,6 +382,29 @@ commands: examples: - playground config open-ccloud-connector-in-browser browser Safari + - name: container-kill-all-before-run + help: | + when running an example, always call playground container kill-all first. If not set, it will call playground stop instead. + args: + - name: enabled + required: false + default: "true" + examples: + - playground config container-kill-all-before-run false + - playground config container-kill-all-before-run true + + - name: check-repo-version + help: | + when running an example, always check if repo version is older than 3 days, if disabled, it will skip this check. + args: + - name: enabled + required: false + default: "true" + examples: + - playground config check-repo-version false + - playground config check-repo-version true + + - name: run group: Run dependencies: @@ -411,7 +434,7 @@ commands: --cluster-creds (or CLUSTER_CREDS environment variable): The Kafka api key and secret to use, it should be separated with colon (example: :) --cluster-schema-registry-creds (or SCHEMA_REGISTRY_CREDS environment variable) (optional, if not set, new one will be created): The Schema Registry api key and secret to use, it should be separated with colon (example: :) - ❗ this command will kill all containers using playground container kill-all + ❗ this command will kill all containers using "playground container kill-all", you can disable this by running "playground config container-kill-all-before-run false" flags: - &environment-run diff --git a/scripts/cli/src/commands/config/check-repo-version.sh b/scripts/cli/src/commands/config/check-repo-version.sh new file mode 100644 index 0000000000..ecdbee1dab --- /dev/null +++ b/scripts/cli/src/commands/config/check-repo-version.sh @@ -0,0 +1,2 @@ +log "📋 configuring check-repo-version with ${args[enabled]}" +playground config set check-repo-version "${args[enabled]}" \ No newline at end of file diff --git a/scripts/cli/src/commands/config/container-kill-all-before-run.sh b/scripts/cli/src/commands/config/container-kill-all-before-run.sh new file mode 100644 index 0000000000..7515084061 --- /dev/null +++ b/scripts/cli/src/commands/config/container-kill-all-before-run.sh @@ -0,0 +1,2 @@ +log "📋 configuring container-kill-all-before-run with ${args[enabled]}" +playground config set container-kill-all-before-run "${args[enabled]}" \ No newline at end of file diff --git a/scripts/cli/src/commands/connector/create-or-update.sh b/scripts/cli/src/commands/connector/create-or-update.sh index 818c5b6f03..da281d6d14 100644 --- a/scripts/cli/src/commands/connector/create-or-update.sh +++ b/scripts/cli/src/commands/connector/create-or-update.sh @@ -200,7 +200,7 @@ then echo "EOF" >> $tmp_dir_clipboard/tmp cat $tmp_dir_clipboard/tmp | pbcopy - log "📋 $connector_type connector config has been copied to the clipboard (disable with 'playground config set clipboard false')" + log "📋 $connector_type connector config has been copied to the clipboard (disable with 'playground config clipboard false')" fi fi fi diff --git a/scripts/cli/src/commands/connector/select-config.sh b/scripts/cli/src/commands/connector/select-config.sh index fdfbb491c7..1d7d78a09e 100644 --- a/scripts/cli/src/commands/connector/select-config.sh +++ b/scripts/cli/src/commands/connector/select-config.sh @@ -67,7 +67,7 @@ do echo "$res" > $tmp_dir/tmp cat $tmp_dir/tmp | pbcopy - log "📋 config has been copied to the clipboard (disable with 'playground config set clipboard false')" + log "📋 config has been copied to the clipboard (disable with 'playground config clipboard false')" fi fi done \ No newline at end of file diff --git a/scripts/cli/src/commands/connector/show-config.sh b/scripts/cli/src/commands/connector/show-config.sh index dd4858141e..cda26bd09f 100644 --- a/scripts/cli/src/commands/connector/show-config.sh +++ b/scripts/cli/src/commands/connector/show-config.sh @@ -62,7 +62,7 @@ do echo "EOF" >> $tmp_dir/tmp cat $tmp_dir/tmp | pbcopy - log "📋 $connector_type connector config has been copied to the clipboard (disable with 'playground config set clipboard false')" + log "📋 $connector_type connector config has been copied to the clipboard (disable with 'playground config clipboard false')" fi fi else @@ -108,7 +108,7 @@ do echo "EOF" >> $tmp_dir/tmp cat $tmp_dir/tmp | pbcopy - log "📋 $connector_type connector config has been copied to the clipboard (disable with 'playground config set clipboard false')" + log "📋 $connector_type connector config has been copied to the clipboard (disable with 'playground config clipboard false')" fi fi fi diff --git a/scripts/cli/src/commands/connector/snippets.sh b/scripts/cli/src/commands/connector/snippets.sh index f1c786f2c3..81cac87e98 100644 --- a/scripts/cli/src/commands/connector/snippets.sh +++ b/scripts/cli/src/commands/connector/snippets.sh @@ -163,7 +163,7 @@ then if [ "$clipboard" == "true" ] || [ "$clipboard" == "" ] then cat $clipboard_file | pbcopy - log "📋 config has been copied to the clipboard (disable with 'playground config set clipboard false')" + log "📋 config has been copied to the clipboard (disable with 'playground config clipboard false')" fi fi fi diff --git a/scripts/cli/src/commands/container/kill-all.sh b/scripts/cli/src/commands/container/kill-all.sh index 2fec3f6b45..a1fd23c0f6 100644 --- a/scripts/cli/src/commands/container/kill-all.sh +++ b/scripts/cli/src/commands/container/kill-all.sh @@ -1,2 +1,2 @@ -log "💀 Kill all docker containers" +log "💀 kill all docker containers" docker rm -f $(docker ps -qa) > /dev/null 2>&1 \ No newline at end of file diff --git a/scripts/cli/src/commands/get-docker-compose.sh b/scripts/cli/src/commands/get-docker-compose.sh index 5d046f1b78..4e5abdd054 100644 --- a/scripts/cli/src/commands/get-docker-compose.sh +++ b/scripts/cli/src/commands/get-docker-compose.sh @@ -11,6 +11,7 @@ then fi echo "$docker_command" > /tmp/tmp sed -e "s|up -d|config|g" \ + -e "s|--quiet-pull||g" \ /tmp/tmp > /tmp/playground-command-config bash /tmp/playground-command-config \ No newline at end of file diff --git a/scripts/cli/src/commands/repro/bootstrap.sh b/scripts/cli/src/commands/repro/bootstrap.sh index 51691e7c55..f27e051dae 100644 --- a/scripts/cli/src/commands/repro/bootstrap.sh +++ b/scripts/cli/src/commands/repro/bootstrap.sh @@ -1290,7 +1290,7 @@ then if [ "$clipboard" == "true" ] || [ "$clipboard" == "" ] then echo "playground run -f $repro_dir/$repro_test_filename"| pbcopy - log "📋 command to run generated example has been copied to the clipboard (disable with 'playground config set clipboard false')" + log "📋 command to run generated example has been copied to the clipboard (disable with 'playground config clipboard false')" fi fi diff --git a/scripts/cli/src/commands/run.sh b/scripts/cli/src/commands/run.sh index d842175a2a..65d75c4178 100644 --- a/scripts/cli/src/commands/run.sh +++ b/scripts/cli/src/commands/run.sh @@ -71,6 +71,22 @@ then verify_installed "confluent" fi +set +e +container_kill_all_before_run=$(playground config get container-kill-all-before-run) +if [ "$container_kill_all_before_run" == "" ] +then + playground config set container-kill-all-before-run true +fi + +if [ "$container_kill_all_before_run" == "true" ] || [ "$container_kill_all_before_run" == "" ] +then + log "💀 kill all docker containers (disable with 'playground config container-kill-all-before-run false')" + playground container kill-all +else + playground stop +fi +set -e + playground state set run.test_file "$test_file" test_file_directory="$(dirname "${test_file}")" filename=$(basename -- "$test_file") @@ -1442,9 +1458,7 @@ else log "🚀 Running example without any flags" fi fi -set +e -playground container kill-all -set -e + playground state set run.connector_type "$(get_connector_type | tr -d '\n')" playground state set run.test_file "$test_file" echo "" >> "$root_folder/playground-run-history" @@ -1461,7 +1475,7 @@ then if [ "$clipboard" == "true" ] || [ "$clipboard" == "" ] then echo "playground run -f $test_file $flag_list" | pbcopy - log "📋 command to run again example has been copied to the clipboard (disable with 'playground config set clipboard false')" + log "📋 command to run again example has been copied to the clipboard (disable with 'playground config clipboard false')" fi fi diff --git a/scripts/cli/src/commands/start-environment.sh b/scripts/cli/src/commands/start-environment.sh index 01c334cbdc..56c8d7e740 100644 --- a/scripts/cli/src/commands/start-environment.sh +++ b/scripts/cli/src/commands/start-environment.sh @@ -13,7 +13,19 @@ fi test_file_directory="$(dirname "${test_file}")" set +e -playground container kill-all +container_kill_all_before_run=$(playground config get container-kill-all-before-run) +if [ "$container_kill_all_before_run" == "" ] +then + playground config set container-kill-all-before-run true +fi + +if [ "$container_kill_all_before_run" == "true" ] || [ "$container_kill_all_before_run" == "" ] +then + log "💀 kill all docker containers (disable with 'playground config container-kill-all-before-run false')" + playground container kill-all +else + playground stop +fi set -e if [[ -n "$wait_for_control_center" ]] diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 135db55e8e..13618e3e32 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -445,29 +445,38 @@ function check_bash_version() { } function check_playground_version() { - set +e - X=3 - git fetch - latest_commit_date=$(git log -1 --format=%cd --date=short) - remote_commit_date=$(git log -1 --format=%cd --date=short origin/master) - - if [[ "$OSTYPE" == "darwin"* ]] + check_repo_version=$(playground config get check-repo-version) + if [ "$check_repo_version" == "" ] then - latest_commit_date_seconds=$(date -j -f "%Y-%m-%d" "$latest_commit_date" +%s) - remote_commit_date_seconds=$(date -j -f "%Y-%m-%d" "$remote_commit_date" +%s) - else - latest_commit_date_seconds=$(date -d "$latest_commit_date" +%s) - remote_commit_date_seconds=$(date -d "$remote_commit_date" +%s) + playground config set check-repo-version true fi - difference=$(( (remote_commit_date_seconds - latest_commit_date_seconds) / (60*60*24) )) - - if [ $difference -gt $X ] + if [ "$check_repo_version" == "true" ] || [ "$check_repo_version" == "" ] then - logwarn "🥶 The current repo version is older than $X days ($difference days), please refresh your version using git pull !" - check_if_continue + set +e + X=3 + git fetch + latest_commit_date=$(git log -1 --format=%cd --date=short) + remote_commit_date=$(git log -1 --format=%cd --date=short origin/master) + + if [[ "$OSTYPE" == "darwin"* ]] + then + latest_commit_date_seconds=$(date -j -f "%Y-%m-%d" "$latest_commit_date" +%s) + remote_commit_date_seconds=$(date -j -f "%Y-%m-%d" "$remote_commit_date" +%s) + else + latest_commit_date_seconds=$(date -d "$latest_commit_date" +%s) + remote_commit_date_seconds=$(date -d "$remote_commit_date" +%s) + fi + + difference=$(( (remote_commit_date_seconds - latest_commit_date_seconds) / (60*60*24) )) + + if [ $difference -gt $X ] + then + logwarn "🥶 The current repo version is older than $X days ($difference days), please refresh your version using git pull ! (disable with 'playground config check-repo-version false')" + check_if_continue + fi + set -e fi - set -e } function set_profiles() { From 1a705e9b001fbae35a374346f8f270d076a0d848 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 27 Sep 2024 16:04:38 +0200 Subject: [PATCH 023/659] 26092024 2 (#13) * Add --initial-state option to "playground connector create-or-update" #5929 * faker location --- .../filestream-sink.sh | 2 +- connect/connect-http-sink/http_no_auth.sh | 2 +- connect/connect-http-sink/http_oauth2_auth.sh | 2 +- scripts/cli/completions.bash | 898 +++++++++--------- scripts/cli/playground | 80 +- scripts/cli/playground.json | 13 +- scripts/cli/playground.yaml | 14 +- .../cli/predefined-schemas/json/users.json | 2 +- scripts/cli/snippets/sink.sh | 2 +- scripts/cli/src/bashly.yml | 18 +- .../commands/connector/create-or-update.sh | 47 +- ...connector-post-template-initial-state.json | 5 + 12 files changed, 621 insertions(+), 464 deletions(-) create mode 100644 scripts/cli/src/create-connector-post-template-initial-state.json diff --git a/connect/connect-filestream-sink/filestream-sink.sh b/connect/connect-filestream-sink/filestream-sink.sh index 6b619c9b53..2b9810020c 100755 --- a/connect/connect-filestream-sink/filestream-sink.sh +++ b/connect/connect-filestream-sink/filestream-sink.sh @@ -26,7 +26,7 @@ playground topic produce -t filestream --nb-messages 5 << 'EOF' "email": "faker.internet.exampleEmail()", "phone": "faker.phone.imei()", "website": "faker.internet.domainName()", - "city": "faker.address.city()", + "city": "faker.location.city()", "company": "faker.company.name()" } ] diff --git a/connect/connect-http-sink/http_no_auth.sh b/connect/connect-http-sink/http_no_auth.sh index e54a271c2b..2fa55a657f 100755 --- a/connect/connect-http-sink/http_no_auth.sh +++ b/connect/connect-http-sink/http_no_auth.sh @@ -32,7 +32,7 @@ playground topic produce -t http-messages --nb-messages 10 << 'EOF' "email": "faker.internet.exampleEmail()", "phone": "faker.phone.imei()", "website": "faker.internet.domainName()", - "city": "faker.address.city()", + "city": "faker.location.city()", "company": "faker.company.name()" } EOF diff --git a/connect/connect-http-sink/http_oauth2_auth.sh b/connect/connect-http-sink/http_oauth2_auth.sh index 87b3b012df..ab33736449 100755 --- a/connect/connect-http-sink/http_oauth2_auth.sh +++ b/connect/connect-http-sink/http_oauth2_auth.sh @@ -32,7 +32,7 @@ playground topic produce -t http-messages --nb-messages 10 << 'EOF' "email": "faker.internet.exampleEmail()", "phone": "faker.phone.imei()", "website": "faker.internet.domainName()", - "city": "faker.address.city()", + "city": "faker.location.city()", "company": "faker.company.name()" } EOF diff --git a/scripts/cli/completions.bash b/scripts/cli/completions.bash index 0fb603ef25..133d4a5e45 100644 --- a/scripts/cli/completions.bash +++ b/scripts/cli/completions.bash @@ -32,20 +32,16 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector open-ccloud-connector-in-browser'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - *'config open-ccloud-connector-in-browser automatically'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'config open-ccloud-connector-in-browser browser'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'connector open-ccloud-connector-in-browser'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container set-environment-variables'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'config open-ccloud-connector-in-browser browser'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'connector offsets get-offsets-request-status'*'-c') @@ -56,12 +52,8 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'topic set-schema-compatibility'*'--compatibility') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") - ;; - - *'connector-plugin search-jar'*'--connector-plugin') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") + *'container set-environment-variables'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'tcp-proxy toggle-writes-client'*'--connection-id') @@ -72,6 +64,18 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; + *'connector-plugin search-jar'*'--connector-plugin') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") + ;; + + *'topic set-schema-compatibility'*'--compatibility') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") + ;; + + *'connector offsets get-offsets-request-status'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + ;; + *'connector open-ccloud-connector-in-browser'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -84,28 +88,28 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'connector offsets get-offsets-request-status'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") - ;; - *'ec2 sync-repro-folder ec2-to-local'*'--instance') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; + *'connector-plugin versions'*'--connector-plugin') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") + ;; + *'connector show-config-parameters'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector-plugin versions'*'--connector-plugin') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") + *'topic produce'*'--value-subject-name-strategy') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") ;; *'connector open-ccloud-connector-in-browser'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--browser --connector --help -c -h")" -- "$cur") ;; - *'topic produce'*'--value-subject-name-strategy') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") + *'connector create-or-update'*'--initial-state') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "RUNNING PAUSED STOPPED")" -- "$cur") ;; *'tcp-proxy close-all-connection-with-error'*) @@ -116,6 +120,10 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; + *'tcp-proxy get-connections'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + ;; + *'topic produce'*'--key-subject-name-strategy') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") ;; @@ -124,43 +132,43 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy get-connections'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + *'config open-ccloud-connector-in-browser'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h automatically browser")" -- "$cur") ;; *'schema set-compatibility'*'--compatibility') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; - *'config open-ccloud-connector-in-browser'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h automatically browser")" -- "$cur") + *'container set-environment-variables'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic set-schema-compatibility'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'connector create-or-update'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container set-environment-variables'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic set-schema-compatibility'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'debug generate-diagnostics'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector create-or-update'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'config container-kill-all-before-run'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'ec2 sync-repro-folder ec2-to-local'*'-i') + *'ec2 sync-repro-folder local-to-ec2'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'ec2 sync-repro-folder local-to-ec2'*'-i') + *'ec2 sync-repro-folder ec2-to-local'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'config container-kill-all-before-run'*) + *'tcp-proxy toggle-accept-connections'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -172,19 +180,15 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy toggle-accept-connections'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'ec2 sync-repro-folder ec2-to-local'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'connector offsets reset'*'--connector') + *'connector show-config-parameters'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector offsets alter'*'--connector') + *'connector select-config'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -192,19 +196,19 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'connector show-config-parameters'*'-c') + *'connector offsets reset'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector select-config'*'--connector') + *'connector offsets alter'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'schema get-compatibility'*'--subject') + *'schema set-compatibility'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'schema set-compatibility'*'--subject') + *'schema get-compatibility'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; @@ -216,19 +220,23 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'connector show-config-parameters'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-refresh --help --only-show-json --open --verbose -c -h -o -v")" -- "$cur") + *'connector offsets get'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector show-config'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'topic produce'*'--compression-codec') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "gzip snappy lz4 zstd")" -- "$cur") ;; *'debug flight-recorder'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector offsets get'*'--connector') + *'connector show-config-parameters'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-refresh --help --only-show-json --open --verbose -c -h -o -v")" -- "$cur") + ;; + + *'connector show-config'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -236,14 +244,6 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'topic produce'*'--compression-codec') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "gzip snappy lz4 zstd")" -- "$cur") - ;; - - *'tcp-proxy toggle-writes-service'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") - ;; - *'debug enable-remote-debugging'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -252,80 +252,76 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic get-number-records'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") - ;; - - *'tcp-proxy toggle-writes-client'*) + *'tcp-proxy toggle-writes-service'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'debug block-traffic'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic get-number-records'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'tcp-proxy toggle-reads-service'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'topic produce'*'--validate-config') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") ;; *'topic display-consumer-offsets'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --verbose -h -v")" -- "$cur") ;; - *'tools install-vscode-extension'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - - *'connector log-level'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'topic produce'*'--validate-config') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") + *'tcp-proxy delay'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; *'tcp-proxy break'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'topic set-schema-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --topic --verbose -h -t -v")" -- "$cur") + *'connector log-level'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tcp-proxy delay'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + *'tcp-proxy toggle-writes-client'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'debug flight-recorder'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") + *'tools install-vscode-extension'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'tools read-parquet-file'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") + *'debug block-traffic'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug enable-remote-debugging'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'tcp-proxy toggle-reads-service'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + ;; + + *'topic set-schema-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --topic --verbose -h -t -v")" -- "$cur") ;; *'connector show-lag'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container change-jdk'*'--version') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "8 11 17 21 22")" -- "$cur") + *'tcp-proxy toggle-reads-client'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + ;; + + *'debug enable-remote-debugging'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; *'connector snippets'*'--converter') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "avro protobuf json-schema json json-schema-enabled string bytearray")" -- "$cur") ;; - *'update-version'*'--connector-jar') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") + *'debug flight-recorder'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") ;; - *'tcp-proxy toggle-reads-client'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'update-version'*'--connector-jar') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") ;; *'connector-plugin search-jar'*'-c') @@ -336,6 +332,18 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") ;; + *'tools read-parquet-file'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") + ;; + + *'container change-jdk'*'--version') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "8 11 17 21 22")" -- "$cur") + ;; + + *'connector create-or-update'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + ;; + *'container unpause'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -344,6 +352,10 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; + *'connector restart'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + *'debug generate-diagnostics'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -352,19 +364,15 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector create-or-update'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - *'container restart'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector create-or-update'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'connector unpause'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector unpause'*'--connector') + *'connector create-or-update'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -372,7 +380,7 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; - *'connector restart'*'--connector') + *'connector update'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -380,80 +388,68 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container resume'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - *'connector resume'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug block-traffic'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") + *'connector-plugin search-jar'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--class --connector-plugin --connector-tag --help -c -h")" -- "$cur") ;; - *'debug java-debug'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector-plugin versions'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; *'connector status'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector-plugin versions'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") - ;; - - *'connector update'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug block-traffic'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") ;; - *'connector-plugin search-jar'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--class --connector-plugin --connector-tag --help -c -h")" -- "$cur") + *'debug java-debug'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container get-properties'*'-c') + *'container resume'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug generate-diagnostics'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'debug heap-dump'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector create-or-update'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level --offsets --package --skip-automatic-connector-config --validate --verbose --wait-for-zero-lag -c -h -l -p -v")" -- "$cur") + *'topic consume'*'--key-subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'container get-ip-addresses'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'debug log-level set'*'--level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'container pause'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector pause'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug log-level set'*'--level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'debug generate-diagnostics'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; *'get-jmx-metrics'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug heap-dump'*'--container') + *'container pause'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tools read-avro-file'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") - ;; - - *'topic consume'*'--key-subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'container get-ip-addresses'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector log-level'*'--level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'tools read-avro-file'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") ;; *'topic get-number-records'*'-t') @@ -464,27 +460,31 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'connector pause'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container get-properties'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector stop'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'connector log-level'*'--level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'debug tcp-dump'*'--container') + *'connector create-or-update'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --initial-state --level --offsets --package --skip-automatic-connector-config --validate --verbose --wait-for-zero-lag -c -h -l -p -v")" -- "$cur") + ;; + + *'container kill'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector offsets reset'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container logs'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector-plugin versions'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-plugin --force-refresh --help --last -c -h")" -- "$cur") + *'debug block-traffic'*'--port') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'container logs'*'--container') + *'debug tcp-dump'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -492,231 +492,227 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug block-traffic'*'--port') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") - ;; - *'ec2 create'*'--instance-type') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "c1.medium c1.xlarge c3.2xlarge c3.4xlarge c3.8xlarge c3.large c3.xlarge c4.2xlarge c4.4xlarge c4.large c4.xlarge m1.large m1.medium m1.small m1.xlarge m2.2xlarge m2.4xlarge m2.xlarge m3.2xlarge m3.large m3.medium m3.xlarge m4.10xlarge m4.2xlarge m4.4xlarge m4.large m4.xlarge t1.micro t2.large t2.medium t2.micro t2.nano t2.small t3.2xlarge")" -- "$cur") ;; - *'connector offsets alter'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - *'config check-repo-version'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'tcp-proxy start'*'--hostname') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector select-config'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tools read-parquet-file'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") + *'connector stop'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container kill'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector offsets alter'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tcp-proxy get-connections'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'repro bootstrap'*'--producer') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") ;; *'repro bootstrap'*'--pipeline') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro --sink-only "$cur")")" -- "$cur") ;; - *'connector select-config'*'-c') + *'connector offsets reset'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'repro bootstrap'*'--producer') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") + *'tools read-parquet-file'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") ;; - *'topic get-number-records'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") + *'tcp-proxy get-connections'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'run'*'--cluster-environment') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-environment-list "$cur")")" -- "$cur") + *'tcp-proxy start'*'--hostname') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'remove-all-docker-images'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'connector-plugin versions'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-plugin --force-refresh --help --last -c -h")" -- "$cur") ;; - *'container get-properties'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'schema get-mode'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; *'container ssh'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'schema register'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'config folder_zip_or_jar'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'schema get-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") + *'run'*'--cluster-environment') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-environment-list "$cur")")" -- "$cur") + ;; + + *'topic produce'*'--reference') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + ;; + + *'container get-properties'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + ;; + + *'remove-all-docker-images'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'schema set-compatibility'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --subject --verbose -h -v")" -- "$cur") ;; - *'schema get-mode'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'schema get-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; *'schema set-mode'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'config folder_zip_or_jar'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - - *'topic produce'*'--reference') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + *'topic get-number-records'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") ;; *'debug java-debug'*'--action') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "enable disable")" -- "$cur") ;; + *'schema register'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + ;; + *'schema register'*'--schema') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'debug flight-recorder'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'cleanup-cloud-resources'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--force --help --resource -h")" -- "$cur") ;; *'connector offsets alter'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'cleanup-cloud-resources'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--force --help --resource -h")" -- "$cur") + *'connector show-config'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'connector select-config'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") ;; - *'connector offsets get'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'tools read-parquet-file'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + *'debug flight-recorder'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'connector offsets reset'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'connector show-config'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'tools read-parquet-file'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'schema delete'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'connector offsets get'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tools read-avro-file'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") + *'container change-jdk'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'debug java-debug'*'--type') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ssl_all ssl_handshake class_loading kerberos")" -- "$cur") ;; - *'container change-jdk'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'tools read-avro-file'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") ;; - *'topic describe'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'schema delete'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'container exec'*'--shell') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") + *'debug flight-recorder'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help -c -h")" -- "$cur") ;; - *'ec2 sync-repro-folder'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h ec2-to-local local-to-ec2")" -- "$cur") + *'debug block-traffic'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'cleanup-cloud-details'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'topic describe'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'schema set-mode'*'--mode') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") + *'debug log-level set'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'connector offsets get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'container exec'*'--shell') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'debug log-level set'*'-l') + *'connector log-level'*'-l') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'tcp-proxy start'*'--port') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") + *'connector log-level'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug flight-recorder'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help -c -h")" -- "$cur") + *'tcp-proxy start'*'--port') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'debug block-traffic'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'schema set-mode'*'--mode') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") ;; - *'connector log-level'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'connector offsets get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'connector log-level'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'connector show-config'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-rest-endpoint --help --verbose -c -h -v")" -- "$cur") ;; *'repro bootstrap'*'--file') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") ;; - *'connector show-config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-rest-endpoint --help --verbose -c -h -v")" -- "$cur") - ;; - - *'ec2 delete'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") + *'cleanup-cloud-details'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'topic consume'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'ec2 sync-repro-folder'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h ec2-to-local local-to-ec2")" -- "$cur") ;; *'tools read-avro-file'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'connector show-lag'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'topic produce'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'topic produce'*'--value') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'topic produce'*'--topic') + *'topic consume'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; @@ -724,90 +720,126 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'container change-jdk'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --version -c -h")" -- "$cur") + *'connector show-lag'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'ec2 delete'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") ;; *'container ssh'*'--shell') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'connector unpause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container change-jdk'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --version -c -h")" -- "$cur") ;; - *'connector open-docs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") + *'container restart'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + + *'debug thread-dump'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'update-version'*'--tag') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") ;; - *'connector log-level'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level -c -h -l")" -- "$cur") + *'schema get'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'connector restart'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'ec2 start'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'run'*'--cluster-region') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-kafka-region-list "$cur")")" -- "$cur") + *'debug log-level set'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --level --package -h -l -p")" -- "$cur") ;; - *'ec2 start'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'debug block-traffic'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --destination --help --port -c -h")" -- "$cur") ;; - *'topic delete'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'connector open-docs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") ;; - *'container restart'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector restart'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug log-level set'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --level --package -h -l -p")" -- "$cur") + *'run'*'--cluster-region') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-kafka-region-list "$cur")")" -- "$cur") + ;; + + *'topic delete'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'debug log-level get'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --package -h -p")" -- "$cur") ;; + *'connector log-level'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level -c -h -l")" -- "$cur") + ;; + *'container unpause'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug block-traffic'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --destination --help --port -c -h")" -- "$cur") + *'connector unpause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug thread-dump'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'container recreate'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --ignore-current-versions -h")" -- "$cur") ;; - *'schema get'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'connector snippets'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--converter --dlq --help -h")" -- "$cur") ;; - *'connector resume'*'-c') + *'ec2 open'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + ;; + + *'connector status'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector versions'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'ec2 stop'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'run'*'--connector-jar') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") + *'topic alter'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + ;; + + *'topic produce'*'--key') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; *'run'*'--cluster-cloud') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure")" -- "$cur") ;; + *'run'*'--connector-jar') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") + ;; + + *'container resume'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + + *'connector resume'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + *'connector delete'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -816,104 +848,72 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector snippets'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--converter --dlq --help -h")" -- "$cur") + *'connector update'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'connector show-lag'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --interval --max-wait --verbose -c -h -v")" -- "$cur") ;; - *'repro import'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") - ;; - - *'connector status'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'connector versions'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'container recreate'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --ignore-current-versions -h")" -- "$cur") + *'repro import'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") ;; *'container kill-all'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'topic alter'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") - ;; - *'run'*'--connector-zip') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") ;; - *'ec2 open'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") - ;; - - *'ec2 stop'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") - ;; - - *'connector update'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - *'get-docker-compose'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'topic produce'*'--key') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") - ;; - - *'container resume'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'container pause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector pause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'connector offsets'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter get get-offsets-request-status reset")" -- "$cur") ;; - *'run'*'--cluster-name') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") - ;; - - *'get-jmx-metrics'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector restart'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'container unpause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'connector plugins'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help --verbose -h -v")" -- "$cur") ;; - *'run'*'--cluster-type') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "basic standard dedicated")" -- "$cur") + *'repro bootstrap'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") ;; - *'connector plugins'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help --verbose -h -v")" -- "$cur") + *'repro bootstrap'*'-p') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") ;; - *'connector pause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'connector unpause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'connector restart'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'container unpause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'debug heap-dump'*'-c') + *'container pause'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector unpause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'debug heap-dump'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'debug thread-dump'*) @@ -924,24 +924,24 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'repro bootstrap'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") + *'run'*'--cluster-type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "basic standard dedicated")" -- "$cur") ;; - *'repro bootstrap'*'-p') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") + *'run'*'--cluster-name') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") ;; - *'run'*'--environment') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") + *'get-jmx-metrics'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container exec'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic describe'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'run'*'--environment') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") ;; *'connector update'*) @@ -952,19 +952,15 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector resume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") - ;; - - *'connector stop'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - *'debug tcp-dump'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container kill'*'-c') + *'connector-plugin'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h search-jar versions")" -- "$cur") + ;; + + *'container exec'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -972,135 +968,147 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help --type -c -h")" -- "$cur") ;; - *'topic describe'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'container resume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; *'container logs'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector status'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'connector stop'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container resume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'connector resume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'connector-plugin'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h search-jar versions")" -- "$cur") + *'connector delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'debug heap-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") + *'connector status'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'schema get-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") + *'container kill'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'container pause'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'topic consume'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'connector pause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'schema set-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") + *'debug log-level'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h get set")" -- "$cur") ;; *'repro bootstrap'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--custom-smt --description --file --help --pipeline -d -f -h")" -- "$cur") ;; - *'container ssh'*'-s') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") + *'debug heap-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") ;; - *'tcp-proxy break'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") + *'topic consume'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'tcp-proxy start'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --delay-service-response --help --hostname --port --service-response-corrupt --skip-automatic-connector-config --throttle-service-response -h")" -- "$cur") ;; - *'get-jmx-metrics'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --domain --help --open -c -d -h -o")" -- "$cur") + *'container ssh'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector pause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'tcp-proxy delay'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") ;; - *'topic produce'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'schema register'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --schema --subject --verbose -h -v")" -- "$cur") ;; - *'container ssh'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'schema get-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; - *'schema register'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --schema --subject --verbose -h -v")" -- "$cur") + *'topic produce'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'tcp-proxy delay'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") + *'tcp-proxy break'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") ;; - *'debug log-level'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h get set")" -- "$cur") + *'get-jmx-metrics'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --domain --help --open -c -d -h -o")" -- "$cur") ;; - *'update-version'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-jar --connector-tag --connector-zip --help --tag -h")" -- "$cur") + *'schema set-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") ;; - *'container logs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") + *'container ssh'*'-s') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'repro import'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") + *'update-version'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-jar --connector-tag --connector-zip --help --tag -h")" -- "$cur") ;; - *'container exec'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--command --container --help --root --shell -c -h")" -- "$cur") + *'connector logs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") ;; *'debug tcp-dump'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --duration --help --port -c -h")" -- "$cur") ;; + *'topic describe'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") + ;; + *'connector stop'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'topic describe'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") + *'container exec'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--command --container --help --root --shell -c -h")" -- "$cur") ;; - *'connector logs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") + *'repro import'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") ;; *'container kill'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; + *'container logs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") + ;; + *'topic delete'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'schema delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --permanent --subject --verbose --version -h -v")" -- "$cur") + *'container ssh'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") ;; - *'config editor'*) + *'topic consume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--grep --help --key-subject --max-characters --max-messages --min-expected-messages --plot-latencies-timestamp-field --tail --timeout --topic --value-subject --verbose -h -t -v")" -- "$cur") + ;; + + *'debug testssl'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -1108,42 +1116,38 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") ;; - *'--output-level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") - ;; - - *'debug testssl'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'topic alter'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'topic consume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--grep --help --key-subject --max-characters --max-messages --min-expected-messages --plot-latencies-timestamp-field --tail --timeout --topic --value-subject --verbose -h -t -v")" -- "$cur") + *'schema delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --permanent --subject --verbose --version -h -v")" -- "$cur") ;; *'switch-ccloud'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'container ssh'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") + *'--output-level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") ;; - *'topic alter'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'config editor'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'repro export'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help -h")" -- "$cur") ;; - *'ec2 delete'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") - ;; - *'repro import'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; + *'ec2 delete'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") + ;; + *'topic create'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --nb-partitions --topic --verbose -h -t -v")" -- "$cur") ;; @@ -1152,10 +1156,6 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --skip-delete-schema --topic --verbose -h -t -v")" -- "$cur") ;; - *'switch-back'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'topic alter'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") ;; @@ -1164,10 +1164,18 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'topic list'*) + *'switch-back'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; + *'schema get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") + ;; + + *'ec2 delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + ;; + *'open'*'--file') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") ;; @@ -1176,20 +1184,28 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; + *'topic list'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + *'ec2 create'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance-type --size --suffix -h")" -- "$cur") ;; - *'ec2 delete'*) + *'ec2 open'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + ;; + + *'ec2 start'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'schema get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") + *'container'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h change-jdk exec get-ip-addresses get-properties kill kill-all logs pause recreate restart resume set-environment-variables ssh unpause")" -- "$cur") ;; - *'ec2 open'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'run'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") ;; *'tcp-proxy'*) @@ -1200,30 +1216,18 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create-or-update delete log-level logs offsets open-ccloud-connector-in-browser open-docs pause plugins restart resume select-config show-config show-config-parameters show-lag snippets status stop unpause update versions")" -- "$cur") ;; - *'container'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h change-jdk exec get-ip-addresses get-properties kill kill-all logs pause recreate restart resume set-environment-variables ssh unpause")" -- "$cur") - ;; - *'open-docs'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") ;; - *'ec2 start'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") - ;; - - *'run'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") + *'run'*'--tag') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") ;; *'ec2 open'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--disable-sync-repro-folder --help --instance -h -i")" -- "$cur") ;; - *'run'*'--tag') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") - ;; - *'ec2 list'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -1236,6 +1240,10 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; + *'re-run'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + *'config'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h check-repo-version clipboard container-kill-all-before-run editor folder_zip_or_jar open-ccloud-connector-in-browser")" -- "$cur") ;; @@ -1244,20 +1252,16 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") ;; - *'status'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'schema'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h delete get get-compatibility get-mode register set-compatibility set-mode")" -- "$cur") ;; - *'re-run'*) + *'status'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'schema'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h delete get get-compatibility get-mode register set-compatibility set-mode")" -- "$cur") - ;; - - *'tools'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h install-vscode-extension read-avro-file read-parquet-file")" -- "$cur") + *'topic'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter consume create delete describe display-consumer-offsets get-number-records list produce set-schema-compatibility")" -- "$cur") ;; *'run'*'-f') @@ -1268,22 +1272,22 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h block-traffic enable-remote-debugging flight-recorder generate-diagnostics heap-dump java-debug log-level tcp-dump testssl thread-dump")" -- "$cur") ;; + *'tools'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h install-vscode-extension read-avro-file read-parquet-file")" -- "$cur") + ;; + *'repro'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h bootstrap export import")" -- "$cur") ;; - *'topic'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter consume create delete describe display-consumer-offsets get-number-records list produce set-schema-compatibility")" -- "$cur") + *'open'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; *'stop'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'open'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") - ;; - *'help'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; diff --git a/scripts/cli/playground b/scripts/cli/playground index 03f270a3bf..8f5941100b 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -144,7 +144,7 @@ playground_usage() { printf " %s ⏸️ Pause connector\n" "$(green "connector pause") " printf " %s 🧞 Get current and latest versions available on Confluent Hub for connector(s) used in example\n" "$(green "connector versions") " printf " %s ♻️ Restart connector\n" "$(green "connector restart") " - printf " %s 🛑 Stop connector (only available if CP > 7.5 )\n" "$(green "connector stop") " + printf " %s 🛑 Stop connector (only available if CP > 7.5)\n" "$(green "connector stop") " printf " %s ⏯️ Resume connector\n" "$(green "connector resume") " printf " %s 🗑️ Delete connector\n" "$(green "connector delete") " printf " %s 🐢 Show lag of sink connector\n" "$(green "connector show-lag") " @@ -4591,7 +4591,7 @@ playground_topic_produce_usage() { # :command.usage_examples printf "%s\n" "$(bold "Examples")" - printf " playground topic produce --tombstone --topic a-topic --key mykey\n \n playground topic produce -t topic-json --nb-messages 10 << 'EOF'\n {\n \"_meta\": {\n \"topic\": \"\",\n \"key\": \"\",\n \"relationships\": []\n },\n \"nested\": {\n \"phone\": \"faker.phone.imei()\",\n \"website\": \"faker.internet.domainName()\"\n },\n \"id\": \"iteration.index\",\n \"name\": \"faker.internet.userName()\",\n \"email\": \"faker.internet.exampleEmail()\",\n \"phone\": \"faker.phone.imei()\",\n \"website\": \"faker.internet.domainName()\",\n \"city\": \"faker.address.city()\",\n \"company\": \"faker.company.name()\"\n }\n EOF\n \n playground topic produce -t topic-avro --nb-messages 10 << 'EOF'\n {\n \"fields\": [\n {\n \"name\": \"count\",\n \"type\": \"long\"\n },\n {\n \"name\": \"first_name\",\n \"type\": \"string\"\n },\n {\n \"name\": \"last_name\",\n \"type\": \"string\"\n },\n {\n \"default\": null,\n \"name\": \"address\",\n \"type\": [\n \"null\",\n \"string\"\n ]\n },\n {\n \"name\": \"last_sale_date\",\n \"type\": {\n \"logicalType\": \"timestamp-millis\",\n \"type\": \"long\"\n }\n },\n {\n \"name\": \"last_sale_price\",\n \"type\": {\n \"logicalType\": \"decimal\",\n \"precision\": 15,\n \"scale\": 2,\n \"type\": \"bytes\"\n }\n },\n {\n \"name\": \"last_connection\",\n \"type\": {\n \"logicalType\": \"date\",\n \"type\": \"int\"\n }\n }\n ],\n \"name\": \"Customer\",\n \"namespace\": \"com.github.vdesabou\",\n \"type\": \"record\"\n }\n EOF\n \n playground topic produce -t topic-json-schema --nb-messages 3 << 'EOF'\n {\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"additionalProperties\": false,\n \"$id\": \"http://lh.test/Customer.schema.json\",\n \"title\": \"Customer\",\n \"description\": \"Customer description\",\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"description\": \"Customer name\",\n \"type\": \"string\",\n \"maxLength\": 25\n },\n \"surname\": {\n \"description\": \"Customer surname\",\n \"type\": \"string\",\n \"minLength\": 2\n },\n \"email\": {\n \"description\": \"Email\",\n \"type\": \"string\",\n \"pattern\": \"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$\"\n }\n },\n \"required\": [\n \"name\",\n \"surname\"\n ]\n }\n EOF\n \n \n playground topic produce -t topic-proto --nb-messages 1 << 'EOF'\n syntax = \"proto3\";\n \n package com.github.vdesabou;\n \n message Customer {\n int64 count = 1;\n string first_name = 2;\n string last_name = 3;\n string address = 4;\n }\n EOF\n \n playground topic produce -t topic-jsql --nb-messages 10 << 'EOF'\n CREATE TABLE \"notused\".\"notused\" (\n \"id\" int PRIMARY KEY,\n \"name\" varchar COMMENT 'faker.internet.userName()',\n \"merchant_id\" int NOT NULL COMMENT 'faker.datatype.number()',\n \"price\" int COMMENT 'faker.datatype.number()',\n \"status\" int COMMENT 'faker.datatype.boolean()',\n \"created_at\" datetime DEFAULT (now())\n );\n EOF\n \n playground topic produce -t topic-json --nb-messages 1 --producer-property\n \"max.request.size=990485760\" < bigjson.json\n \n playground topic produce -t topic-string --nb-messages 5000 << 'EOF'\n Ad et ut pariatur officia eos.\n Nesciunt fugit nam libero ut qui itaque sed earum at itaque nesciunt eveniet\n atque.\n Quidem libero quis quod et illum excepturi voluptas et in perspiciatis iusto\n neque.\n Quibusdam commodi explicabo dolores molestiae qui delectus dolorum fugiat\n molestiae natus assumenda omnis expedita.\n Et sunt aut architecto suscipit fugiat qui voluptate iure vel doloremque eum\n culpa.\n Qui enim facilis eos similique aperiam totam eius et at dolor dolores.\n Ut sunt quia qui quia consectetur aut reiciendis.\n Modi adipisci iusto aut voluptatem dolores laudantium.\n Sequi sint quia quibusdam molestias minus et aliquid voluptatum aliquam.\n Rerum aut amet quo possimus nihil velit quisquam ut cumque.\n Pariatur ad officiis voluptatibus quia vel corporis ea fugit adipisci porro.\n EOF\n \n # key and headers\n # mykey1 %%g can also be used\n playground topic produce -t topic-json-multiple-lines --nb-messages 10 --key\n \"mykey1\" --headers \"header1:value1,header2:value2\" << 'EOF'\n {\"u_name\": \"scissors\", \"u_price\": 2.75, \"u_quantity\": 3}\n {\"u_name\": \"tape\", \"u_price\": 0.99, \"u_quantity\": 10}\n {\"u_name\": \"notebooks\", \"u_price\": 1.99, \"u_quantity\": 5}\n EOF\n \n # avro key\n playground topic produce -t topic-avro-with-key --nb-messages 10 --key '\n {\n \"fields\": [\n {\n \"name\": \"id\",\n \"type\": \"long\"\n }\n ],\n \"name\": \"Key\",\n \"namespace\": \"com.github.vdesabou\",\n \"type\": \"record\"\n }\n ' << 'EOF'\n {\n \"fields\": [\n {\n \"doc\": \"count\",\n \"name\": \"count\",\n \"type\": \"long\"\n },\n {\n \"doc\": \"First Name of Customer\",\n \"name\": \"first_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Last Name of Customer\",\n \"name\": \"last_name\",\n \"type\": \"string\"\n }\n ],\n \"name\": \"Customer\",\n \"namespace\": \"com.github.vdesabou\",\n \"type\": \"record\"\n }\n EOF\n \n # tombstone\n playground topic produce -t topic-json-multiple-lines --tombstone --key\n \"mykey1\"\n \n # input file\n playground topic produce -t topic-avro-example3 < avro-schema.avsc\n \n # record-size\n playground topic produce -t topic-avro-example-big-size --nb-messages 3\n --record-size 10000000 << 'EOF'\n {\n \"fields\": [\n {\n \"doc\": \"count\",\n \"name\": \"count\",\n \"type\": \"long\"\n },\n {\n \"doc\": \"First Name of Customer\",\n \"name\": \"first_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Last Name of Customer\",\n \"name\": \"last_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Address of Customer\",\n \"name\": \"address\",\n \"type\": \"string\"\n }\n ],\n \"name\": \"Customer\",\n \"namespace\": \"com.github.vdesabou\",\n \"type\": \"record\"\n }\n EOF\n \n # validate\n playground topic produce -t topic-json-schema-validate --nb-messages 3\n --validate << 'EOF'\n {\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"additionalProperties\": false,\n \"$id\": \"http://lh.test/Customer.schema.json\",\n \"title\": \"Customer\",\n \"description\": \"Customer description\",\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"description\": \"Customer name\",\n \"type\": \"string\",\n \"maxLength\": 25\n },\n \"surname\": {\n \"description\": \"Customer surname\",\n \"type\": \"string\",\n \"minLength\": 2\n },\n \"email\": {\n \"description\": \"Email\",\n \"type\": \"string\",\n \"pattern\": \"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$\"\n },\n \"holiday\": {\n \"oneOf\": [\n {\n \"title\": \"Not included\",\n \"type\": \"null\"\n },\n {}\n ]\n },\n \"f2\": {}\n },\n \"required\": [\n \"name\",\n \"surname\"\n ]\n }\n EOF\n \n # --value-subject-name-strategy\n playground topic produce -t topic-avro-example-value-subject-name-strategy\n --nb-messages 10 --value-subject-name-strategy TopicRecordNameStrategy <<\n 'EOF'\n {\n \"fields\": [\n {\n \"doc\": \"count\",\n \"name\": \"count\",\n \"type\": \"long\"\n },\n {\n \"doc\": \"First Name of Customer\",\n \"name\": \"first_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Last Name of Customer\",\n \"name\": \"last_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Address of Customer\",\n \"name\": \"address\",\n \"type\": \"string\"\n }\n ],\n \"name\": \"Customer\",\n \"namespace\": \"com.github.vdesabou\",\n \"type\": \"record\"\n }\n EOF\n \n # --generate-only\n playground topic produce -t topic-avro-example-forced-value --nb-messages 10 \n --generate-only << 'EOF'\n {\n \"fields\": [\n {\n \"doc\": \"count\",\n \"name\": \"count\",\n \"type\": \"long\"\n },\n {\n \"doc\": \"First Name of Customer\",\n \"name\": \"first_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Last Name of Customer\",\n \"name\": \"last_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Address of Customer\",\n \"name\": \"address\",\n \"type\": \"string\"\n },\n {\n \"name\": \"createdDate\",\n \"type\": {\n \"logicalType\": \"timestamp-millis\",\n \"type\": \"long\"\n }\n },\n {\n \"default\": null,\n \"name\": \"warranty_expiration\",\n \"type\": [\n \"null\",\n {\n \"logicalType\": \"date\",\n \"type\": \"int\"\n }\n ]\n }\n ],\n \"name\": \"Customer\",\n \"namespace\": \"com.github.vdesabou\",\n \"type\": \"record\"\n }\n EOF\n \n # --forced-value\n playground topic produce -t topic-avro-example-forced-value --nb-messages 1\n --forced-value '{\"count\":4,\"first_name\":\"Vincent\",\"last_name\":\"de\n Saboulin\",\"address\":\"xxx\",\"createdDate\":1697852606000,\"warranty_expiration\":{\"int\":19653}}'\n << 'EOF'\n {\n \"fields\": [\n {\n \"doc\": \"count\",\n \"name\": \"count\",\n \"type\": \"long\"\n },\n {\n \"doc\": \"First Name of Customer\",\n \"name\": \"first_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Last Name of Customer\",\n \"name\": \"last_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Address of Customer\",\n \"name\": \"address\",\n \"type\": \"string\"\n },\n {\n \"name\": \"createdDate\",\n \"type\": {\n \"logicalType\": \"timestamp-millis\",\n \"type\": \"long\"\n }\n },\n {\n \"default\": null,\n \"name\": \"warranty_expiration\",\n \"type\": [\n \"null\",\n {\n \"logicalType\": \"date\",\n \"type\": \"int\"\n }\n ]\n }\n ],\n \"name\": \"Customer\",\n \"namespace\": \"com.github.vdesabou\",\n \"type\": \"record\"\n }\n EOF\n \n # json schema references\n playground topic produce --value\n /path/to/scripts/cli/predefined-schemas/json-schema/schema-reference/customer.json\n --reference\n /path/to/scripts/cli/predefined-schemas/json-schema/schema-reference/address.json\n --reference\n /path/to/scripts/cli/predefined-schemas/json-schema/schema-reference/email.json\n --topic customers\n" + printf " playground topic produce --tombstone --topic a-topic --key mykey\n \n playground topic produce -t topic-json --nb-messages 10 << 'EOF'\n {\n \"_meta\": {\n \"topic\": \"\",\n \"key\": \"\",\n \"relationships\": []\n },\n \"nested\": {\n \"phone\": \"faker.phone.imei()\",\n \"website\": \"faker.internet.domainName()\"\n },\n \"id\": \"iteration.index\",\n \"name\": \"faker.internet.userName()\",\n \"email\": \"faker.internet.exampleEmail()\",\n \"phone\": \"faker.phone.imei()\",\n \"website\": \"faker.internet.domainName()\",\n \"city\": \"faker.location.city()\",\n \"company\": \"faker.company.name()\"\n }\n EOF\n \n playground topic produce -t topic-avro --nb-messages 10 << 'EOF'\n {\n \"fields\": [\n {\n \"name\": \"count\",\n \"type\": \"long\"\n },\n {\n \"name\": \"first_name\",\n \"type\": \"string\"\n },\n {\n \"name\": \"last_name\",\n \"type\": \"string\"\n },\n {\n \"default\": null,\n \"name\": \"address\",\n \"type\": [\n \"null\",\n \"string\"\n ]\n },\n {\n \"name\": \"last_sale_date\",\n \"type\": {\n \"logicalType\": \"timestamp-millis\",\n \"type\": \"long\"\n }\n },\n {\n \"name\": \"last_sale_price\",\n \"type\": {\n \"logicalType\": \"decimal\",\n \"precision\": 15,\n \"scale\": 2,\n \"type\": \"bytes\"\n }\n },\n {\n \"name\": \"last_connection\",\n \"type\": {\n \"logicalType\": \"date\",\n \"type\": \"int\"\n }\n }\n ],\n \"name\": \"Customer\",\n \"namespace\": \"com.github.vdesabou\",\n \"type\": \"record\"\n }\n EOF\n \n playground topic produce -t topic-json-schema --nb-messages 3 << 'EOF'\n {\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"additionalProperties\": false,\n \"$id\": \"http://lh.test/Customer.schema.json\",\n \"title\": \"Customer\",\n \"description\": \"Customer description\",\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"description\": \"Customer name\",\n \"type\": \"string\",\n \"maxLength\": 25\n },\n \"surname\": {\n \"description\": \"Customer surname\",\n \"type\": \"string\",\n \"minLength\": 2\n },\n \"email\": {\n \"description\": \"Email\",\n \"type\": \"string\",\n \"pattern\": \"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$\"\n }\n },\n \"required\": [\n \"name\",\n \"surname\"\n ]\n }\n EOF\n \n \n playground topic produce -t topic-proto --nb-messages 1 << 'EOF'\n syntax = \"proto3\";\n \n package com.github.vdesabou;\n \n message Customer {\n int64 count = 1;\n string first_name = 2;\n string last_name = 3;\n string address = 4;\n }\n EOF\n \n playground topic produce -t topic-jsql --nb-messages 10 << 'EOF'\n CREATE TABLE \"notused\".\"notused\" (\n \"id\" int PRIMARY KEY,\n \"name\" varchar COMMENT 'faker.internet.userName()',\n \"merchant_id\" int NOT NULL COMMENT 'faker.datatype.number()',\n \"price\" int COMMENT 'faker.datatype.number()',\n \"status\" int COMMENT 'faker.datatype.boolean()',\n \"created_at\" datetime DEFAULT (now())\n );\n EOF\n \n playground topic produce -t topic-json --nb-messages 1 --producer-property\n \"max.request.size=990485760\" < bigjson.json\n \n playground topic produce -t topic-string --nb-messages 5000 << 'EOF'\n Ad et ut pariatur officia eos.\n Nesciunt fugit nam libero ut qui itaque sed earum at itaque nesciunt eveniet\n atque.\n Quidem libero quis quod et illum excepturi voluptas et in perspiciatis iusto\n neque.\n Quibusdam commodi explicabo dolores molestiae qui delectus dolorum fugiat\n molestiae natus assumenda omnis expedita.\n Et sunt aut architecto suscipit fugiat qui voluptate iure vel doloremque eum\n culpa.\n Qui enim facilis eos similique aperiam totam eius et at dolor dolores.\n Ut sunt quia qui quia consectetur aut reiciendis.\n Modi adipisci iusto aut voluptatem dolores laudantium.\n Sequi sint quia quibusdam molestias minus et aliquid voluptatum aliquam.\n Rerum aut amet quo possimus nihil velit quisquam ut cumque.\n Pariatur ad officiis voluptatibus quia vel corporis ea fugit adipisci porro.\n EOF\n \n # key and headers\n # mykey1 %%g can also be used\n playground topic produce -t topic-json-multiple-lines --nb-messages 10 --key\n \"mykey1\" --headers \"header1:value1,header2:value2\" << 'EOF'\n {\"u_name\": \"scissors\", \"u_price\": 2.75, \"u_quantity\": 3}\n {\"u_name\": \"tape\", \"u_price\": 0.99, \"u_quantity\": 10}\n {\"u_name\": \"notebooks\", \"u_price\": 1.99, \"u_quantity\": 5}\n EOF\n \n # avro key\n playground topic produce -t topic-avro-with-key --nb-messages 10 --key '\n {\n \"fields\": [\n {\n \"name\": \"id\",\n \"type\": \"long\"\n }\n ],\n \"name\": \"Key\",\n \"namespace\": \"com.github.vdesabou\",\n \"type\": \"record\"\n }\n ' << 'EOF'\n {\n \"fields\": [\n {\n \"doc\": \"count\",\n \"name\": \"count\",\n \"type\": \"long\"\n },\n {\n \"doc\": \"First Name of Customer\",\n \"name\": \"first_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Last Name of Customer\",\n \"name\": \"last_name\",\n \"type\": \"string\"\n }\n ],\n \"name\": \"Customer\",\n \"namespace\": \"com.github.vdesabou\",\n \"type\": \"record\"\n }\n EOF\n \n # tombstone\n playground topic produce -t topic-json-multiple-lines --tombstone --key\n \"mykey1\"\n \n # input file\n playground topic produce -t topic-avro-example3 < avro-schema.avsc\n \n # record-size\n playground topic produce -t topic-avro-example-big-size --nb-messages 3\n --record-size 10000000 << 'EOF'\n {\n \"fields\": [\n {\n \"doc\": \"count\",\n \"name\": \"count\",\n \"type\": \"long\"\n },\n {\n \"doc\": \"First Name of Customer\",\n \"name\": \"first_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Last Name of Customer\",\n \"name\": \"last_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Address of Customer\",\n \"name\": \"address\",\n \"type\": \"string\"\n }\n ],\n \"name\": \"Customer\",\n \"namespace\": \"com.github.vdesabou\",\n \"type\": \"record\"\n }\n EOF\n \n # validate\n playground topic produce -t topic-json-schema-validate --nb-messages 3\n --validate << 'EOF'\n {\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"additionalProperties\": false,\n \"$id\": \"http://lh.test/Customer.schema.json\",\n \"title\": \"Customer\",\n \"description\": \"Customer description\",\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"description\": \"Customer name\",\n \"type\": \"string\",\n \"maxLength\": 25\n },\n \"surname\": {\n \"description\": \"Customer surname\",\n \"type\": \"string\",\n \"minLength\": 2\n },\n \"email\": {\n \"description\": \"Email\",\n \"type\": \"string\",\n \"pattern\": \"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$\"\n },\n \"holiday\": {\n \"oneOf\": [\n {\n \"title\": \"Not included\",\n \"type\": \"null\"\n },\n {}\n ]\n },\n \"f2\": {}\n },\n \"required\": [\n \"name\",\n \"surname\"\n ]\n }\n EOF\n \n # --value-subject-name-strategy\n playground topic produce -t topic-avro-example-value-subject-name-strategy\n --nb-messages 10 --value-subject-name-strategy TopicRecordNameStrategy <<\n 'EOF'\n {\n \"fields\": [\n {\n \"doc\": \"count\",\n \"name\": \"count\",\n \"type\": \"long\"\n },\n {\n \"doc\": \"First Name of Customer\",\n \"name\": \"first_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Last Name of Customer\",\n \"name\": \"last_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Address of Customer\",\n \"name\": \"address\",\n \"type\": \"string\"\n }\n ],\n \"name\": \"Customer\",\n \"namespace\": \"com.github.vdesabou\",\n \"type\": \"record\"\n }\n EOF\n \n # --generate-only\n playground topic produce -t topic-avro-example-forced-value --nb-messages 10 \n --generate-only << 'EOF'\n {\n \"fields\": [\n {\n \"doc\": \"count\",\n \"name\": \"count\",\n \"type\": \"long\"\n },\n {\n \"doc\": \"First Name of Customer\",\n \"name\": \"first_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Last Name of Customer\",\n \"name\": \"last_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Address of Customer\",\n \"name\": \"address\",\n \"type\": \"string\"\n },\n {\n \"name\": \"createdDate\",\n \"type\": {\n \"logicalType\": \"timestamp-millis\",\n \"type\": \"long\"\n }\n },\n {\n \"default\": null,\n \"name\": \"warranty_expiration\",\n \"type\": [\n \"null\",\n {\n \"logicalType\": \"date\",\n \"type\": \"int\"\n }\n ]\n }\n ],\n \"name\": \"Customer\",\n \"namespace\": \"com.github.vdesabou\",\n \"type\": \"record\"\n }\n EOF\n \n # --forced-value\n playground topic produce -t topic-avro-example-forced-value --nb-messages 1\n --forced-value '{\"count\":4,\"first_name\":\"Vincent\",\"last_name\":\"de\n Saboulin\",\"address\":\"xxx\",\"createdDate\":1697852606000,\"warranty_expiration\":{\"int\":19653}}'\n << 'EOF'\n {\n \"fields\": [\n {\n \"doc\": \"count\",\n \"name\": \"count\",\n \"type\": \"long\"\n },\n {\n \"doc\": \"First Name of Customer\",\n \"name\": \"first_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Last Name of Customer\",\n \"name\": \"last_name\",\n \"type\": \"string\"\n },\n {\n \"doc\": \"Address of Customer\",\n \"name\": \"address\",\n \"type\": \"string\"\n },\n {\n \"name\": \"createdDate\",\n \"type\": {\n \"logicalType\": \"timestamp-millis\",\n \"type\": \"long\"\n }\n },\n {\n \"default\": null,\n \"name\": \"warranty_expiration\",\n \"type\": [\n \"null\",\n {\n \"logicalType\": \"date\",\n \"type\": \"int\"\n }\n ]\n }\n ],\n \"name\": \"Customer\",\n \"namespace\": \"com.github.vdesabou\",\n \"type\": \"record\"\n }\n EOF\n \n # json schema references\n playground topic produce --value\n /path/to/scripts/cli/predefined-schemas/json-schema/schema-reference/customer.json\n --reference\n /path/to/scripts/cli/predefined-schemas/json-schema/schema-reference/address.json\n --reference\n /path/to/scripts/cli/predefined-schemas/json-schema/schema-reference/email.json\n --topic customers\n" echo fi @@ -4856,7 +4856,7 @@ playground_connector_usage() { printf " %s ⏸️ Pause connector\n" "$(green "pause") " printf " %s 🧞 Get current and latest versions available on Confluent Hub for connector(s) used in example\n" "$(green "versions") " printf " %s ♻️ Restart connector\n" "$(green "restart") " - printf " %s 🛑 Stop connector (only available if CP > 7.5 )\n" "$(green "stop") " + printf " %s 🛑 Stop connector (only available if CP > 7.5)\n" "$(green "stop") " printf " %s ⏯️ Resume connector\n" "$(green "resume") " printf " %s 🗑️ Delete connector\n" "$(green "delete") " printf " %s 🐢 Show lag of sink connector\n" "$(green "show-lag") " @@ -5232,7 +5232,7 @@ playground_connector_restart_usage() { # :command.usage playground_connector_stop_usage() { - printf "playground connector stop - 🛑 Stop connector (only available if CP > 7.5 )\n\n" + printf "playground connector stop - 🛑 Stop connector (only available if CP > 7.5)\n\n" printf "%s\n" "$(bold "== Usage ==")" printf " playground connector stop [OPTIONS]\n" @@ -5739,6 +5739,12 @@ playground_connector_create_or_update_usage() { printf " 📍 Create connector with offsets\n (https://docs.confluent.io/cloud/current/connectors/offsets.html#create-connectors-with-offsets)\n \n ⚠️ Only available for ccloud connectors, the connector should not really\n exists\n" echo + # :flag.usage + printf " %s\n" "$(magenta "--initial-state INITIAL-STATE")" + printf " 🪵 Create connector with specific status\n (https://cwiki.apache.org/confluence/display/KAFKA/KIP-980%%3A+Allow+creating+connectors+in+a+stopped+state)\n \n Only available if CP > 7.7\n \n ⚠️ not available for ccloud connectors\n" + printf " %s\n" "Allowed: RUNNING, PAUSED, STOPPED" + echo + # :command.usage_fixed_flags printf " %s\n" "$(magenta "--help, -h")" printf " Show this help\n" @@ -24212,6 +24218,7 @@ playground_connector_create_or_update_command() { verbose="${args[--verbose]}" no_clipboard="${args[--no-clipboard]}" offsets=${args[--offsets]} + initial_state=${args[--initial-state]} connector_type=$(playground state get run.connector_type) @@ -24230,6 +24237,21 @@ playground_connector_create_or_update_command() { fi fi + if [[ -n "$initial_state" ]] + then + tag=$(docker ps --format '{{.Image}}' | egrep 'confluentinc/cp-.*-connect-base:' | awk -F':' '{print $2}') + if [ $? != 0 ] || [ "$tag" == "" ] + then + logerror "❌ could not find current CP version from docker ps" + exit 1 + fi + + if ! version_gt $tag "7.6.99"; then + logerror "❌ --initial-state is available since CP 7.7 only" + exit 1 + fi + fi + environment=$(playground state get run.environment_before_switch) if [ "$environment" = "" ] then @@ -24259,6 +24281,7 @@ playground_connector_create_or_update_command() { json_file=$tmp_dir/connector.json new_json_file=$tmp_dir/connector_new.json connector_with_offsets_file=$tmp_dir/connector_with_offsets.json + connector_with_initial_state_file=$tmp_dir/connector_with_initial_state.json json_validate_file=$tmp_dir/json_validate_file echo "$json_content" > $json_file @@ -24417,6 +24440,12 @@ then exit 1 fi + if [[ -n "$initial_state" ]] + then + logerror "❌ --initial-state is set but not supported with $connector_type connector" + exit 1 + fi + get_ccloud_connect if [[ -n "$offsets" ]] then @@ -24440,6 +24469,11 @@ else logerror "❌ --offsets is set but not supported with $connector_type connector" exit 1 fi + if [[ -n "$initial_state" ]] && [ $is_create == 0 ] + then + logerror "❌ --initial-state is set but $connector_type connector $connector already exists" + exit 1 + fi get_connect_url_and_security if [[ -n "$skip_automatic_connector_config" ]] then @@ -24447,8 +24481,24 @@ else else add_connector_config_based_on_environment "$environment" "$json_content" fi - echo "$json_content" > $new_json_file - handle_onprem_connect_rest_api "curl $security -s -X PUT -H \"Content-Type: application/json\" --data @$new_json_file $connect_url/connectors/$connector/config" + + if [[ -n "$initial_state" ]] + then + log "🪵 creating $connector_type connector $connector with --initial-state: $initial_state" + + # add mandatory name field + new_json_content=$(echo $json_content | jq -c ". + {\"name\": \"$connector\"}") + + sed -e "s|:CONNECTOR_NAME:|$connector|g" \ + -e "s|:CONNECTOR_CONFIG:|$new_json_content|g" \ + -e "s|:CONNECTOR_INITIAL_STATE:|$initial_state|g" \ + $root_folder/scripts/cli/src/create-connector-post-template-initial-state.json > ${connector_with_initial_state_file} + + handle_onprem_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" --data @$connector_with_initial_state_file $connect_url/connectors" + else + echo "$json_content" > $new_json_file + handle_onprem_connect_rest_api "curl $security -s -X PUT -H \"Content-Type: application/json\" --data @$new_json_file $connect_url/connectors/$connector/config" + fi fi if [[ -n "$level" ]] @@ -37793,6 +37843,20 @@ playground_connector_create_or_update_parse_requirements() { fi ;; + # :flag.case + --initial-state) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + args['--initial-state']="$2" + shift + shift + else + printf "%s\n" "--initial-state requires an argument: --initial-state INITIAL-STATE" >&2 + exit 1 + fi + ;; + -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 @@ -37842,6 +37906,10 @@ playground_connector_create_or_update_parse_requirements() { printf "%s\n" "--level must be one of: INFO, WARN, DEBUG, TRACE" >&2 exit 1 fi + if [[ ${args['--initial-state']:-} ]] && [[ ! ${args['--initial-state']:-} =~ ^(RUNNING|PAUSED|STOPPED)$ ]]; then + printf "%s\n" "--initial-state must be one of: RUNNING, PAUSED, STOPPED" >&2 + exit 1 + fi } diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index e894900820..ec8e9af675 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -2275,7 +2275,7 @@ }, { "name": "stop", - "description": "🛑 Stop connector (only available if CP > 7.5 )\n", + "description": "🛑 Stop connector (only available if CP > 7.5)\n", "usage": "playground connector stop [OPTIONS]", "options": [ { @@ -2697,6 +2697,17 @@ ], "argument": "OFFSETS", "description": "📍 Create connector with offsets (https://docs.confluent.io/cloud/current/connectors/offsets.html#create-connectors-with-offsets)\n\n⚠️ Only available for ccloud connectors, the connector should not really exists\n" + }, + { + "names": [ + "--initial-state" + ], + "argument": [ + "RUNNING", + "PAUSED", + "STOPPED" + ], + "description": "🪵 Create connector with specific status (https://cwiki.apache.org/confluence/display/KAFKA/KIP-980%3A+Allow+creating+connectors+in+a+stopped+state)\n\nOnly available if CP > 7.7\n\n⚠️ not available for ccloud connectors\n\nAllowed values: RUNNING, PAUSED, STOPPED\n" } ] }, diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index a8ed108bc2..47c870ecb7 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -2431,7 +2431,7 @@ subcommands: - name: stop description: | - 🛑 Stop connector (only available if CP > 7.5 ) + 🛑 Stop connector (only available if CP > 7.5) usage: playground connector stop [OPTIONS] options: - names: @@ -2833,6 +2833,18 @@ subcommands: ⚠️ Only available for ccloud connectors, the connector should not really exists + - names: + - --initial-state + argument: [RUNNING, PAUSED, STOPPED] + description: | + 🪵 Create connector with specific status (https://cwiki.apache.org/confluence/display/KAFKA/KIP-980%3A+Allow+creating+connectors+in+a+stopped+state) + + Only available if CP > 7.7 + + ⚠️ not available for ccloud connectors + + Allowed values: RUNNING, PAUSED, STOPPED + - name: update description: | 🛠️ Update connector configuration by opening current connector config in text editor set with playground config editor (default is code). Once file is saved, the new configuration is updated. diff --git a/scripts/cli/predefined-schemas/json/users.json b/scripts/cli/predefined-schemas/json/users.json index 57fe1eb1ec..1547b4bf66 100644 --- a/scripts/cli/predefined-schemas/json/users.json +++ b/scripts/cli/predefined-schemas/json/users.json @@ -14,6 +14,6 @@ "email": "faker.internet.exampleEmail()", "phone": "faker.phone.imei()", "website": "faker.internet.domainName()", - "city": "faker.address.city()", + "city": "faker.location.city()", "company": "faker.company.name()" } \ No newline at end of file diff --git a/scripts/cli/snippets/sink.sh b/scripts/cli/snippets/sink.sh index 93aeb15568..d9a11f761c 100644 --- a/scripts/cli/snippets/sink.sh +++ b/scripts/cli/snippets/sink.sh @@ -111,7 +111,7 @@ playground topic produce -t topic-json --nb-messages 5 << 'EOF' "email": "faker.internet.exampleEmail()", "phone": "faker.phone.imei()", "website": "faker.internet.domainName()", - "city": "faker.address.city()", + "city": "faker.location.city()", "company": "faker.company.name()" } ] diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index c8a5ebfbc8..9cb40ef299 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -2477,7 +2477,7 @@ commands: "email": "faker.internet.exampleEmail()", "phone": "faker.phone.imei()", "website": "faker.internet.domainName()", - "city": "faker.address.city()", + "city": "faker.location.city()", "company": "faker.company.name()" } EOF @@ -3076,7 +3076,7 @@ commands: - *connector - name: stop - help: 🛑 Stop connector (only available if CP > 7.5 ) + help: 🛑 Stop connector (only available if CP > 7.5) flags: - *verbose - *connector @@ -3299,6 +3299,20 @@ commands: ⚠️ Only available for ccloud connectors, the connector should not really exists + - long: --initial-state + arg: initial-state + allowed: + - RUNNING + - PAUSED + - STOPPED + required: false + help: |- + 🪵 Create connector with specific status (https://cwiki.apache.org/confluence/display/KAFKA/KIP-980%3A+Allow+creating+connectors+in+a+stopped+state) + + Only available if CP > 7.7 + + ⚠️ not available for ccloud connectors + examples: | playground connector create-or-update -c filestream-sink << EOF { diff --git a/scripts/cli/src/commands/connector/create-or-update.sh b/scripts/cli/src/commands/connector/create-or-update.sh index da281d6d14..5953bfc99c 100644 --- a/scripts/cli/src/commands/connector/create-or-update.sh +++ b/scripts/cli/src/commands/connector/create-or-update.sh @@ -8,6 +8,7 @@ skip_automatic_connector_config=${args[--skip-automatic-connector-config]} verbose="${args[--verbose]}" no_clipboard="${args[--no-clipboard]}" offsets=${args[--offsets]} +initial_state=${args[--initial-state]} connector_type=$(playground state get run.connector_type) @@ -26,6 +27,21 @@ then fi fi +if [[ -n "$initial_state" ]] +then + tag=$(docker ps --format '{{.Image}}' | egrep 'confluentinc/cp-.*-connect-base:' | awk -F':' '{print $2}') + if [ $? != 0 ] || [ "$tag" == "" ] + then + logerror "❌ could not find current CP version from docker ps" + exit 1 + fi + + if ! version_gt $tag "7.6.99"; then + logerror "❌ --initial-state is available since CP 7.7 only" + exit 1 + fi +fi + environment=$(playground state get run.environment_before_switch) if [ "$environment" = "" ] then @@ -55,6 +71,7 @@ fi json_file=$tmp_dir/connector.json new_json_file=$tmp_dir/connector_new.json connector_with_offsets_file=$tmp_dir/connector_with_offsets.json +connector_with_initial_state_file=$tmp_dir/connector_with_initial_state.json json_validate_file=$tmp_dir/json_validate_file echo "$json_content" > $json_file @@ -213,6 +230,12 @@ then exit 1 fi + if [[ -n "$initial_state" ]] + then + logerror "❌ --initial-state is set but not supported with $connector_type connector" + exit 1 + fi + get_ccloud_connect if [[ -n "$offsets" ]] then @@ -235,6 +258,11 @@ else logerror "❌ --offsets is set but not supported with $connector_type connector" exit 1 fi + if [[ -n "$initial_state" ]] && [ $is_create == 0 ] + then + logerror "❌ --initial-state is set but $connector_type connector $connector already exists" + exit 1 + fi get_connect_url_and_security if [[ -n "$skip_automatic_connector_config" ]] then @@ -242,8 +270,23 @@ else else add_connector_config_based_on_environment "$environment" "$json_content" fi - echo "$json_content" > $new_json_file - handle_onprem_connect_rest_api "curl $security -s -X PUT -H \"Content-Type: application/json\" --data @$new_json_file $connect_url/connectors/$connector/config" + + if [[ -n "$initial_state" ]] + then + log "🪵 creating $connector_type connector $connector with --initial-state: $initial_state" + # add mandatory name field + new_json_content=$(echo $json_content | jq -c ". + {\"name\": \"$connector\"}") + + sed -e "s|:CONNECTOR_NAME:|$connector|g" \ + -e "s|:CONNECTOR_CONFIG:|$new_json_content|g" \ + -e "s|:CONNECTOR_INITIAL_STATE:|$initial_state|g" \ + $root_folder/scripts/cli/src/create-connector-post-template-initial-state.json > ${connector_with_initial_state_file} + + handle_onprem_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" --data @$connector_with_initial_state_file $connect_url/connectors" + else + echo "$json_content" > $new_json_file + handle_onprem_connect_rest_api "curl $security -s -X PUT -H \"Content-Type: application/json\" --data @$new_json_file $connect_url/connectors/$connector/config" + fi fi if [[ -n "$level" ]] diff --git a/scripts/cli/src/create-connector-post-template-initial-state.json b/scripts/cli/src/create-connector-post-template-initial-state.json new file mode 100644 index 0000000000..b0c4ee5e94 --- /dev/null +++ b/scripts/cli/src/create-connector-post-template-initial-state.json @@ -0,0 +1,5 @@ +{ + "name": ":CONNECTOR_NAME:", + "config": :CONNECTOR_CONFIG:, + "initial_state": ":CONNECTOR_INITIAL_STATE:" +} \ No newline at end of file From bf7444f7004a11ac1c4aa0c784840539caa032ce Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 8 Oct 2024 10:57:30 +0200 Subject: [PATCH 024/659] wip (#14) * 3.5.3 * playground connector show-lag issue when used with --environment ccloud example #5943 * remove connect-jms-sag-um-source and connect-jms-sag-um-sink examples as Docker image is no longer provided by SAG #5949 * wip --- .github/workflows/ci.yml | 2 +- connect/connect-iceberg-sink/spark/Dockerfile | 2 +- connect/connect-jms-sag-um-sink/README.md | 105 ------------------ .../docker-compose.plaintext.yml | 31 ------ .../jms-sag-um-sink.sh | 98 ---------------- connect/connect-jms-sag-um-sink/stop.sh | 8 -- connect/connect-jms-sag-um-source/README.md | 76 ------------- .../docker-compose.plaintext.yml | 29 ----- .../jms-sag-um-source.sh | 90 --------------- connect/connect-jms-sag-um-source/stop.sh | 8 -- docs/content-template.md | 2 - scripts/arm64-support-with-emulation.txt | 2 - scripts/cli/playground | 11 +- .../src/commands/connector/offsets/alter.sh | 3 +- .../cli/src/commands/connector/offsets/get.sh | 3 +- .../src/commands/connector/offsets/reset.sh | 2 +- .../cli/src/commands/connector/show-lag.sh | 3 +- secrets.tar.gpg | Bin 7456 -> 7243 bytes 18 files changed, 16 insertions(+), 459 deletions(-) delete mode 100644 connect/connect-jms-sag-um-sink/README.md delete mode 100644 connect/connect-jms-sag-um-sink/docker-compose.plaintext.yml delete mode 100755 connect/connect-jms-sag-um-sink/jms-sag-um-sink.sh delete mode 100755 connect/connect-jms-sag-um-sink/stop.sh delete mode 100644 connect/connect-jms-sag-um-source/README.md delete mode 100644 connect/connect-jms-sag-um-source/docker-compose.plaintext.yml delete mode 100755 connect/connect-jms-sag-um-source/jms-sag-um-source.sh delete mode 100755 connect/connect-jms-sag-um-source/stop.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8cdaacd93f..83b5182809 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -108,7 +108,7 @@ jobs: "🚀 connect/connect-salesforce-bulkapi-sink connect/connect-salesforce-bulkapi-source connect/connect-salesforce-pushtopics-source connect/connect-salesforce-sobject-sink connect/connect-salesforce-cdc-source connect/connect-salesforce-platform-events-sink connect/connect-salesforce-platform-events-source", "🚀 connect/connect-splunk-sink connect/connect-splunk-source connect/connect-splunk-s2s-source connect/connect-spool-dir-source connect/connect-syslog-source other/connect-override-policy-sftp-sink other/connect-override-policy-sftp-source", "🚀 connect/connect-minio-s3-sink connect/connect-marketo-source connect/connect-active-mq-sink connect/connect-active-mq-source connect/connect-lenses-active-mq-source connect/connect-cassandra-sink connect/connect-couchbase-sink connect/connect-couchbase-source connect/connect-hbase-sink", - "🚀 connect/connect-jms-tibco-sink connect/connect-jms-tibco-source connect/connect-debezium-mongodb-source connect/connect-debezium-mysql-source connect/connect-debezium-postgresql-source connect/connect-debezium-sqlserver-source connect/connect-elasticsearch-sink connect/connect-datadiode-source-sink connect/connect-jms-sag-um-source connect/connect-jms-sag-um-sink", + "🚀 connect/connect-jms-tibco-sink connect/connect-jms-tibco-source connect/connect-debezium-mongodb-source connect/connect-debezium-mysql-source connect/connect-debezium-postgresql-source connect/connect-debezium-sqlserver-source connect/connect-elasticsearch-sink connect/connect-datadiode-source-sink", "🚀 connect/connect-hdfs2-sink connect/connect-hdfs2-source connect/connect-hdfs3-sink connect/connect-hdfs3-source connect/connect-ibm-mq-sink connect/connect-ibm-mq-source connect/connect-snmp-source connect/connect-omnisci-sink", "🚀 connect/connect-cdc-oracle11-source connect/connect-jdbc-oracle11-sink connect/connect-jdbc-oracle11-source connect/connect-influxdb-sink connect/connect-influxdb-source connect/connect-jdbc-mysql-sink connect/connect-jdbc-mysql-source connect/connect-jdbc-postgresql-sink connect/connect-jdbc-postgresql-source connect/connect-jdbc-sqlserver-sink", "🚀 connect/connect-jdbc-sqlserver-source connect/connect-jdbc-vertica-sink connect/connect-singlestore-sink connect/connect-jdbc-singlestore-source connect/connect-jms-active-mq-source connect/connect-jms-active-mq-sink connect/connect-jms-solace-sink connect/connect-jms-solace-source connect/connect-mongodb-sink connect/connect-mongodb-source connect/connect-mqtt-sink connect/connect-mqtt-source connect/connect-neo4j-sink connect/connect-tibco-sink connect/connect-tibco-source", diff --git a/connect/connect-iceberg-sink/spark/Dockerfile b/connect/connect-iceberg-sink/spark/Dockerfile index 801cdcb975..bd8760a55b 100644 --- a/connect/connect-iceberg-sink/spark/Dockerfile +++ b/connect/connect-iceberg-sink/spark/Dockerfile @@ -48,7 +48,7 @@ ENV PYTHONPATH=$SPARK_HOME/python:$SPARK_HOME/python/lib/py4j-0.10.9.7-src.zip:$ WORKDIR ${SPARK_HOME} -ENV SPARK_VERSION=3.5.2 +ENV SPARK_VERSION=3.5.3 ENV SPARK_MAJOR_VERSION=3.5 ENV ICEBERG_VERSION=1.5.0 diff --git a/connect/connect-jms-sag-um-sink/README.md b/connect/connect-jms-sag-um-sink/README.md deleted file mode 100644 index c99c33a0fd..0000000000 --- a/connect/connect-jms-sag-um-sink/README.md +++ /dev/null @@ -1,105 +0,0 @@ -# JMS Software AG Universal Messaging Sink Connector - - - -## Objective - -Quickly test [JMS Sink - SAG Universal Messaging](https://docs.confluent.io/kafka-connect-jms-sink/current/overview.html#features) connector. - - - - -## How to run - -Simply run: - -``` -$ just use command and search for jms-sag-um-sink.sh in this folder -``` - - -## Details of what the script is doing - -Create `QueueConnectionFactory` queue connection faftory in the SAG Universal Messaging Server - -```bash -$ docker exec umserver runUMTool.sh CreateConnectionFactory -rname=nsp://localhost:9000 -connectionurl=nsp://umserver:9000 -factoryname=QueueConnectionFactory -factorytype=queue - -``` - -Create `test.queue` queue in the SAG Universal Messaging Server - -```bash -$ docker exec umserver runUMTool.sh CreateJMSQueue -rname=nsp://localhost:9000 -queuename=test.queue - -``` - -Publish messages to the Solace queue using the REST endpoint - -```bash -$ seq 10 | docker exec -i broker kafka-console-producer --broker-list broker:9092 --topic sink-messages - -``` - -The connector is created with: - -```bash -$ curl -X PUT \ - -H "Content-Type: application/json" \ - --data '{ - "connector.class": "io.confluent.connect.jms.JmsSinkConnector", - "tasks.max": "1", - "topics": "sink-messages", - "java.naming.provider.url": "nsp://umserver:9000", - "java.naming.factory.initial": "com.pcbsys.nirvana.nSpace.NirvanaContextFactory", - "connection.factory.name": "QueueConnectionFactory", - "java.naming.security.principal": "admin", - "java.naming.security.credentials": "admin", - "jms.destination.type": "queue", - "jms.destination.name": "test-queue", - "nirvana.useJMSEngine": "true", - "key.converter": "org.apache.kafka.connect.storage.StringConverter", - "value.converter": "org.apache.kafka.connect.storage.StringConverter", - "confluent.topic.bootstrap.servers": "broker:9092", - "confluent.topic.replication.factor": "1" - }' \ - http://localhost:8083/connectors/jms-sag-um-sink/config | jq . -``` -Verify the messages in the topic - -``` -$ docker exec -it umserver timeout 30 runUMTool.sh JMSSubscribe -rname=nsp://localhost:9000 -connectionfactory=QueueConnectionFactory -destination=test-queue -We have initialised JMSSubscribe with: {rname=nsp://localhost:9000, destination=test-queue, connectionfactory=QueueConnectionFactory} -Now receiving messages... press enter to exit -JMS MSG ID : ID:172.22.0.6:36341:116724326203392:1 -JMS DELIVERY MODE : 2 -JMS TIME STAMP : 1659665628137 -JMS PROPERTIES : ----------------------------------------------------------------- ----------------------------------------------------------------- -JMS MSG ID : ID:172.22.0.6:36341:116724326203392:2 -JMS DELIVERY MODE : 2 -JMS TIME STAMP : 1659665628158 -JMS PROPERTIES : ----------------------------------------------------------------- ----------------------------------------------------------------- -JMS MSG ID : ID:172.22.0.6:36341:116724326203392:3 -JMS DELIVERY MODE : 2 -JMS TIME STAMP : 1659665628158 -JMS PROPERTIES : ----------------------------------------------------------------- ----------------------------------------------------------------- -JMS MSG ID : ID:172.22.0.6:36341:116724326203392:4 -JMS DELIVERY MODE : 2 -JMS TIME STAMP : 1659665628158 -JMS PROPERTIES : ----------------------------------------------------------------- ----------------------------------------------------------------- -JMS MSG ID : ID:172.22.0.6:36341:116724326203392:5 -JMS DELIVERY MODE : 2 -JMS TIME STAMP : 1659665628158 -JMS PROPERTIES : ----------------------------------------------------------------- -.... -``` - diff --git a/connect/connect-jms-sag-um-sink/docker-compose.plaintext.yml b/connect/connect-jms-sag-um-sink/docker-compose.plaintext.yml deleted file mode 100644 index f76d11a00b..0000000000 --- a/connect/connect-jms-sag-um-sink/docker-compose.plaintext.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- -services: - umserver: - image: softwareag/universalmessaging-server:10.11 - hostname: umserver - container_name: umserver - ports: - - 9000:9000 - tmpfs: /dev/shm - ulimits: - nofile: - soft: 2448 - hard: 38048 - environment: - REALM_NAME: umtest - INIT_JAVA_MEM_SIZE: 2048 - MAX_JAVA_MEM_SIZE: 2048 - MAX_DIRECT_MEM_SIZE: 2G - BASIC_AUTH_ENABLE: N - BASIC_AUTH_MANDATORY: N - - connect: - depends_on: - - umserver - volumes: - - ../../connect/connect-jms-sag-um-sink/nClient.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jms-sink/lib/nClient.jar - - ../../connect/connect-jms-sag-um-sink/nJMS.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jms-sink/lib/nJMS.jar - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jms-sink - CONNECT_LOG4J_LOGGERS: org.reflections=ERROR,io.confluent.connect.jms=DEBUG,com.pcbsys.nirvana.nJMS=DEBUG - \ No newline at end of file diff --git a/connect/connect-jms-sag-um-sink/jms-sag-um-sink.sh b/connect/connect-jms-sag-um-sink/jms-sag-um-sink.sh deleted file mode 100755 index 4e4a3e25ee..0000000000 --- a/connect/connect-jms-sag-um-sink/jms-sag-um-sink.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash -set -e - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -source ${DIR}/../../scripts/utils.sh - -# required to make utils.sh script being able to work, do not remove: -# PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} -#playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" - -function wait_for_um () { - MAX_WAIT=240 - CUR_WAIT=0 - log "⌛ Waiting up to $MAX_WAIT seconds for Universal Messaging to startup" - docker container logs umserver > /tmp/out.txt 2>&1 - while ! grep "Scheduling shutdown in" /tmp/out.txt > /dev/null; - do - sleep 10 - docker container logs umserver > /tmp/out.txt 2>&1 - CUR_WAIT=$(( CUR_WAIT+10 )) - if [[ "$CUR_WAIT" -gt "$MAX_WAIT" ]]; then - echo -e "\nERROR: The logs in all connect containers do not show 'Scheduling shutdown in' after $MAX_WAIT seconds. Please troubleshoot with 'docker container ps' and 'docker container logs'.\n" - exit 1 - fi - done - log "Universal Messaging Server is started!" - sleep 30 -} - - -docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.yml" down -v --remove-orphans -log "Starting up SAG Universal Messaging container to get Client libraries" -docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.yml" up -d umserver - -wait_for_um -log "Universal Messaging Realm Server is up" - -if [ ! -f nClient.jar ] -then - docker cp umserver:/opt/softwareag/UniversalMessaging/lib/nClient.jar nClient.jar -fi -if [ ! -f nJMS.jar ] -then - docker cp umserver:/opt/softwareag/UniversalMessaging/lib/nJMS.jar nJMS.jar -fi - -docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.yml" up -d --quiet-pull -command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.yml" up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" -playground state set run.docker_command "$command" -playground state set run.environment "plaintext" - -wait_container_ready - - -log "Create Connection Factory" -docker exec umserver runUMTool.sh CreateConnectionFactory -rname=nsp://localhost:9000 -connectionurl=nsp://umserver:9000 -factoryname=QueueConnectionFactory -factorytype=queue - -log "Create Queue" -docker exec umserver runUMTool.sh CreateJMSQueue -rname=nsp://localhost:9000 -queuename=test-queue - -log "Sending messages to topic sink-messages" -playground topic produce -t sink-messages --nb-messages 10 << 'EOF' -%g -EOF - -log "Creating JMS Sink - SAG Universal Messaging connector" -playground connector create-or-update --connector jms-sag-um-sink << EOF -{ - "connector.class": "io.confluent.connect.jms.JmsSinkConnector", - "tasks.max": "1", - "topics": "sink-messages", - "java.naming.provider.url": "nsp://umserver:9000", - "java.naming.factory.initial": "com.pcbsys.nirvana.nSpace.NirvanaContextFactory", - "connection.factory.name": "QueueConnectionFactory", - "java.naming.security.principal": "admin", - "java.naming.security.credentials": "admin", - "jms.destination.type": "queue", - "jms.destination.name": "test-queue", - "key.converter": "org.apache.kafka.connect.storage.StringConverter", - "value.converter": "org.apache.kafka.connect.storage.StringConverter", - "confluent.topic.bootstrap.servers": "broker:9092", - "confluent.topic.replication.factor": "1" -} -EOF - -playground connector show-lag --connector jms-sag-um-sink - -if [ ! -z "$GITHUB_RUN_NUMBER" ] -then - # running with github actions - # it is sometime failing in CI, so relying on consumer lag being 0 to have the test successful instead - exit 0 -fi - -log "Confirm the messages were delivered to the test-queue queue" -docker exec -i umserver timeout 10 runUMTool.sh JMSSubscribe -rname=nsp://localhost:9000 -connectionfactory=QueueConnectionFactory -destination=test-queue > /tmp/result.log 2>&1 -cat /tmp/result.log -grep "JMS MSG ID" /tmp/result.log \ No newline at end of file diff --git a/connect/connect-jms-sag-um-sink/stop.sh b/connect/connect-jms-sag-um-sink/stop.sh deleted file mode 100755 index bab6807da5..0000000000 --- a/connect/connect-jms-sag-um-sink/stop.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - - - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -source ${DIR}/../../scripts/utils.sh - -stop_all "$DIR" \ No newline at end of file diff --git a/connect/connect-jms-sag-um-source/README.md b/connect/connect-jms-sag-um-source/README.md deleted file mode 100644 index 7adb830b36..0000000000 --- a/connect/connect-jms-sag-um-source/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# JMS Software AG Universal Messaging Source Connector - - - -## Objective - -Quickly test [JMS Source - SAG Universal Messaging](https://docs.confluent.io/kafka-connect-jms-source/current/overview.html#features) connector. - - -## How to run - -Simply run: - -``` -$ just use command and search for jms-sag-um-source.sh in this folder -``` - -## Details of what the script is doing - -Create `QueueConnectionFactory` queue connection faftory in the SAG Universal Messaging Server - -```bash -$ docker exec umserver runUMTool.sh CreateConnectionFactory -rname=nsp://localhost:9000 -connectionurl=nsp://umserver:9000 -factoryname=QueueConnectionFactory -factorytype=queue - -``` - -Create `test.queue` queue in the SAG Universal Messaging Server - -```bash -$ docker exec umserver runUMTool.sh CreateJMSQueue -rname=nsp://localhost:9000 -queuename=test.queue - -``` - -Publish messages to the SAG Universal Messaging queue - -```bash -$ for i in 1000 1001 1002 -do - docker exec umserver runUMTool.sh JMSPublish -rname=nsp://localhost:9000 -connectionfactory=QueueConnectionFactory -destination=test.queue -message=hello$i -done -``` - -The connector is created with: - -```bash -$ curl -X PUT \ - -H "Content-Type: application/json" \ - --data '{ - "connector.class": "io.confluent.connect.jms.JmsSourceConnector", - "tasks.max": "1", - "kafka.topic": "source-messages", - "java.naming.provider.url": "nsp://umserver:9000", - "java.naming.factory.initial": "com.pcbsys.nirvana.nSpace.NirvanaContextFactory", - "connection.factory.name": "QueueConnectionFactory", - "__java.naming.security.principal": "admin", - "__java.naming.security.credentials": "admin", - "jms.destination.type": "queue", - "jms.destination.name": "test.queue", - "key.converter": "org.apache.kafka.connect.storage.StringConverter", - "value.converter": "org.apache.kafka.connect.storage.StringConverter", - "confluent.topic.bootstrap.servers": "broker:9092", - "confluent.topic.replication.factor": "1" - }' \ - http://localhost:8083/connectors/jms-sag-um-source/config | jq . - -``` -Verify topic - -``` -playground topic consume --topic source-messages --min-expected-messages 3 --timeout 60 -Struct{messageID=ID:172.20.0.2:34661:98195837288448:1,messageType=text,timestamp=1659664813908,deliveryMode=2,destination=Struct{destinationType=queue,name=test.queue},redelivered=false,expiration=0,priority=4,properties={},text=hello1000} -Struct{messageID=ID:172.20.0.2:37603:98204427223040:1,messageType=text,timestamp=1659664815508,deliveryMode=2,destination=Struct{destinationType=queue,name=test.queue},redelivered=false,expiration=0,priority=4,properties={},text=hello1001} -Struct{messageID=ID:172.20.0.2:47379:98213017157632:1,messageType=text,timestamp=1659664817508,deliveryMode=2,destination=Struct{destinationType=queue,name=test.queue},redelivered=false,expiration=0,priority=4,properties={},text=hello1002} -Processed a total of 3 messages -``` - diff --git a/connect/connect-jms-sag-um-source/docker-compose.plaintext.yml b/connect/connect-jms-sag-um-source/docker-compose.plaintext.yml deleted file mode 100644 index 2a084e4033..0000000000 --- a/connect/connect-jms-sag-um-source/docker-compose.plaintext.yml +++ /dev/null @@ -1,29 +0,0 @@ ---- -services: - umserver: - image: softwareag/universalmessaging-server:10.11 - hostname: umserver - container_name: umserver - ports: - - 9000:9000 - tmpfs: /dev/shm - ulimits: - nofile: - soft: 2448 - hard: 38048 - environment: - REALM_NAME: umtest - INIT_JAVA_MEM_SIZE: 2048 - MAX_JAVA_MEM_SIZE: 2048 - MAX_DIRECT_MEM_SIZE: 2G - BASIC_AUTH_ENABLE: N - BASIC_AUTH_MANDATORY: N - - connect: - depends_on: - - umserver - volumes: - - ../../connect/connect-jms-sag-um-source/nClient.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jms/lib/nClient.jar - - ../../connect/connect-jms-sag-um-source/nJMS.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jms/lib/nJMS.jar - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jms diff --git a/connect/connect-jms-sag-um-source/jms-sag-um-source.sh b/connect/connect-jms-sag-um-source/jms-sag-um-source.sh deleted file mode 100755 index f724fd45c8..0000000000 --- a/connect/connect-jms-sag-um-source/jms-sag-um-source.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/bash -set -e - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -source ${DIR}/../../scripts/utils.sh - -# required to make utils.sh script being able to work, do not remove: -# PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} -#playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" - -function wait_for_um () { - MAX_WAIT=240 - CUR_WAIT=0 - log "⌛ Waiting up to $MAX_WAIT seconds for Universal Messaging to startup" - docker container logs umserver > /tmp/out.txt 2>&1 - while ! grep "Scheduling shutdown in" /tmp/out.txt > /dev/null; - do - sleep 10 - docker container logs umserver > /tmp/out.txt 2>&1 - CUR_WAIT=$(( CUR_WAIT+10 )) - if [[ "$CUR_WAIT" -gt "$MAX_WAIT" ]]; then - echo -e "\nERROR: The logs in all connect containers do not show 'Scheduling shutdown in' after $MAX_WAIT seconds. Please troubleshoot with 'docker container ps' and 'docker container logs'.\n" - exit 1 - fi - done - log "Universal Messaging Server is started!" - sleep 30 -} - - -docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.yml" down -v --remove-orphans -log "Starting up SAG Universal Messaging container to get Client libraries" -docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.yml" up -d umserver - -wait_for_um -log "Universal Messaging Realm Server is up" - -if [ ! -f nClient.jar ] -then - docker cp umserver:/opt/softwareag/UniversalMessaging/lib/nClient.jar nClient.jar -fi -if [ ! -f nJMS.jar ] -then - docker cp umserver:/opt/softwareag/UniversalMessaging/lib/nJMS.jar nJMS.jar - -fi - -docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.yml" up -d --quiet-pull -command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.yml" up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" -playground state set run.docker_command "$command" -playground state set run.environment "plaintext" - -wait_container_ready - -log "Create Connection Factory" -docker exec umserver runUMTool.sh CreateConnectionFactory -rname=nsp://localhost:9000 -connectionurl=nsp://umserver:9000 -factoryname=QueueConnectionFactory -factorytype=queue - -log "Create Queue" -docker exec umserver runUMTool.sh CreateJMSQueue -rname=nsp://localhost:9000 -queuename=test.queue - -log "Publish messages to the queue" -for i in 1000 1001 1002 -do - docker exec umserver runUMTool.sh JMSPublish -rname=nsp://localhost:9000 -connectionfactory=QueueConnectionFactory -destination=test.queue -message=hello$i -done - -log "Creating Solace source connector" -playground connector create-or-update --connector jms-sag-um-source << EOF -{ - "connector.class": "io.confluent.connect.jms.JmsSourceConnector", - "tasks.max": "1", - "kafka.topic": "source-messages", - "java.naming.provider.url": "nsp://umserver:9000", - "java.naming.factory.initial": "com.pcbsys.nirvana.nSpace.NirvanaContextFactory", - "connection.factory.name": "QueueConnectionFactory", - "__java.naming.security.principal": "admin", - "__java.naming.security.credentials": "admin", - "jms.destination.type": "queue", - "jms.destination.name": "test.queue", - "key.converter": "org.apache.kafka.connect.storage.StringConverter", - "value.converter": "org.apache.kafka.connect.storage.StringConverter", - "confluent.topic.bootstrap.servers": "broker:9092", - "confluent.topic.replication.factor": "1" -} -EOF - -sleep 10 - -log "Verifying topic source-messages" -playground topic consume --topic source-messages --min-expected-messages 3 --timeout 60 \ No newline at end of file diff --git a/connect/connect-jms-sag-um-source/stop.sh b/connect/connect-jms-sag-um-source/stop.sh deleted file mode 100755 index bab6807da5..0000000000 --- a/connect/connect-jms-sag-um-source/stop.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - - - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -source ${DIR}/../../scripts/utils.sh - -stop_all "$DIR" \ No newline at end of file diff --git a/docs/content-template.md b/docs/content-template.md index 83f3bbc403..e707975699 100644 --- a/docs/content-template.md +++ b/docs/content-template.md @@ -107,8 +107,6 @@ * [JMS ActiveMQ Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-jms-active-mq-source) :connect/connect-jms-active-mq-source: * [JMS ActiveMQ Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-jms-active-mq-sink) :connect/connect-jms-active-mq-sink: * [Lenses JMS ActiveMQ Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-lenses-active-mq-source) :connect/connect-lenses-active-mq-source: -* [JMS Software AG Universal Messaging Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-jms-sag-um-source) :connect/connect-jms-sag-um-source: -* [JMS Software AG Universal Messaging Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-jms-sag-um-sink) :connect/connect-jms-sag-um-sink: * [JMS Solace Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-jms-solace-sink) :connect/connect-jms-solace-sink: * [JMS Solace Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-jms-solace-source) :connect/connect-jms-solace-source: * [JMS TIBCO EMS Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-jms-tibco-sink) :connect/connect-jms-tibco-sink: diff --git a/scripts/arm64-support-with-emulation.txt b/scripts/arm64-support-with-emulation.txt index b84a66c21e..24692d05d9 100644 --- a/scripts/arm64-support-with-emulation.txt +++ b/scripts/arm64-support-with-emulation.txt @@ -22,8 +22,6 @@ connect/connect-jdbc-snowflake-source connect/connect-jdbc-sqlserver-sink connect/connect-jdbc-sqlserver-source connect/connect-jms-active-mq-sink -connect/connect-jms-sag-um-sink -connect/connect-jms-sag-um-source connect/connect-jms-tibco-sink connect/connect-jms-tibco-source connect/connect-tibco-sink diff --git a/scripts/cli/playground b/scripts/cli/playground index 8f5941100b..3d10054809 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -22027,6 +22027,7 @@ playground_connector_offsets_get_command() { verbose="${args[--verbose]}" connector_type=$(playground state get run.connector_type) + get_environment_used if [[ ! -n "$connector" ]] then @@ -22038,7 +22039,7 @@ playground_connector_offsets_get_command() { fi fi - if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] + if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] || [ "$environment" == "ccloud" ] then get_ccloud_connect get_kafka_docker_playground_dir @@ -22165,7 +22166,7 @@ playground_connector_offsets_reset_command() { fi fi - if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] + if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] || [ "$environment" == "ccloud" ] then get_ccloud_connect get_kafka_docker_playground_dir @@ -22316,6 +22317,7 @@ playground_connector_offsets_alter_command() { verbose="${args[--verbose]}" connector_type=$(playground state get run.connector_type) + get_environment_used if [[ ! -n "$connector" ]] then @@ -22327,7 +22329,7 @@ playground_connector_offsets_alter_command() { fi fi - if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] + if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] || [ "$environment" == "ccloud" ] then get_ccloud_connect get_kafka_docker_playground_dir @@ -23004,6 +23006,7 @@ playground_connector_show_lag_command() { max_wait="${args[--max-wait]}" connector_type=$(playground state get run.connector_type) + get_environment_used if [[ ! -n "$connector" ]] then @@ -23015,7 +23018,7 @@ playground_connector_show_lag_command() { fi fi - if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] + if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] || [ "$environment" == "ccloud" ] then get_ccloud_connect get_kafka_docker_playground_dir diff --git a/scripts/cli/src/commands/connector/offsets/alter.sh b/scripts/cli/src/commands/connector/offsets/alter.sh index 8f5b586a02..e24a374d4a 100644 --- a/scripts/cli/src/commands/connector/offsets/alter.sh +++ b/scripts/cli/src/commands/connector/offsets/alter.sh @@ -2,6 +2,7 @@ connector="${args[--connector]}" verbose="${args[--verbose]}" connector_type=$(playground state get run.connector_type) +get_environment_used if [[ ! -n "$connector" ]] then @@ -13,7 +14,7 @@ then fi fi -if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] +if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] || [ "$environment" == "ccloud" ] then get_ccloud_connect get_kafka_docker_playground_dir diff --git a/scripts/cli/src/commands/connector/offsets/get.sh b/scripts/cli/src/commands/connector/offsets/get.sh index 38c38f78ae..0afe2be349 100644 --- a/scripts/cli/src/commands/connector/offsets/get.sh +++ b/scripts/cli/src/commands/connector/offsets/get.sh @@ -2,6 +2,7 @@ connector="${args[--connector]}" verbose="${args[--verbose]}" connector_type=$(playground state get run.connector_type) +get_environment_used if [[ ! -n "$connector" ]] then @@ -13,7 +14,7 @@ then fi fi -if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] +if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] || [ "$environment" == "ccloud" ] then get_ccloud_connect get_kafka_docker_playground_dir diff --git a/scripts/cli/src/commands/connector/offsets/reset.sh b/scripts/cli/src/commands/connector/offsets/reset.sh index 7b457a110a..341eb9994a 100644 --- a/scripts/cli/src/commands/connector/offsets/reset.sh +++ b/scripts/cli/src/commands/connector/offsets/reset.sh @@ -13,7 +13,7 @@ then fi fi -if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] +if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] || [ "$environment" == "ccloud" ] then get_ccloud_connect get_kafka_docker_playground_dir diff --git a/scripts/cli/src/commands/connector/show-lag.sh b/scripts/cli/src/commands/connector/show-lag.sh index 1361dcf301..8dcb13d842 100644 --- a/scripts/cli/src/commands/connector/show-lag.sh +++ b/scripts/cli/src/commands/connector/show-lag.sh @@ -4,6 +4,7 @@ interval="${args[--interval]}" max_wait="${args[--max-wait]}" connector_type=$(playground state get run.connector_type) +get_environment_used if [[ ! -n "$connector" ]] then @@ -15,7 +16,7 @@ then fi fi -if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] +if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] || [ "$environment" == "ccloud" ] then get_ccloud_connect get_kafka_docker_playground_dir diff --git a/secrets.tar.gpg b/secrets.tar.gpg index 572d4f5a39bf5947b0f22669b0f1111a35022546..f7b0b40bdb56b0309bd4f80c6fab566926149d86 100644 GIT binary patch literal 7243 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 Z$=)BQ(|=dSh(dl8|M=t|_x~5=LrPF7{3ZYZ literal 7456 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 From 8b14f8616ac250b9fe54876a36e4263b54c95b54 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 16 Oct 2024 10:12:25 +0200 Subject: [PATCH 025/659] wip (#15) * https://github.com/vdesabou/kafka-docker-playground/issues/5187 * delete retry --- ccloud/fm-snowflake-sink/fully-managed-snowflake-sink.sh | 6 +----- ...assuming-iam-role-with-custom-aws-credential-provider.sh | 1 + connect/connect-aws-sqs-source/sqs-source-proxy.sh | 1 + .../sqs-source-with-assuming-iam-role.sh | 1 + connect/connect-aws-sqs-source/sqs-source.sh | 1 + connect/connect-jdbc-snowflake-sink/jdbc-snowflake-sink.sh | 6 +----- .../connect-jdbc-snowflake-source/jdbc-snowflake-source.sh | 6 +----- connect/connect-snowflake-sink/README.md | 6 +----- connect/connect-snowflake-sink/snowflake-sink-proxy.sh | 6 +----- .../snowflake-sink-snowpipe-streaming.sh | 6 +----- connect/connect-snowflake-sink/snowflake-sink.sh | 6 +----- 11 files changed, 11 insertions(+), 35 deletions(-) diff --git a/ccloud/fm-snowflake-sink/fully-managed-snowflake-sink.sh b/ccloud/fm-snowflake-sink/fully-managed-snowflake-sink.sh index 0494ba9a84..8fd759c1ea 100755 --- a/ccloud/fm-snowflake-sink/fully-managed-snowflake-sink.sh +++ b/ccloud/fm-snowflake-sink/fully-managed-snowflake-sink.sh @@ -82,6 +82,7 @@ GRANT USAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE ACCOUNTADMIN; GRANT CREATE TABLE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT CREATE STAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT CREATE PIPE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; +GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO ROLE ACCOUNTADMIN; EOF log "Create a Snowflake WAREHOUSE (for admin purpose as KafkaConnect is Serverless)" @@ -116,11 +117,6 @@ USE ROLE SECURITYADMIN; GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO USER $PLAYGROUND_USER; EOF -docker run --quiet --rm -i -e SNOWSQL_PWD="$SNOWFLAKE_PASSWORD" -e RSA_PUBLIC_KEY="$RSA_PUBLIC_KEY" kurron/snowsql --username $SNOWFLAKE_USERNAME -a $SNOWFLAKE_ACCOUNT_NAME << EOF -USE ROLE SYSADMIN; -GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO ROLE ACCOUNTADMIN; -EOF - log "Creating test_table topic in Confluent Cloud (auto.create.topics.enable=false)" set +e playground topic create --topic test_table diff --git a/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh b/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh index 7396d27ac2..aeb07c6025 100755 --- a/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh +++ b/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh @@ -106,6 +106,7 @@ then # You must wait 60 seconds after deleting a queue before you can create another with the same name log "Sleeping 60 seconds" sleep 60 + aws sqs delete-queue --queue-url ${QUEUE_URL} fi set -e diff --git a/connect/connect-aws-sqs-source/sqs-source-proxy.sh b/connect/connect-aws-sqs-source/sqs-source-proxy.sh index a61783f25b..d922e41239 100755 --- a/connect/connect-aws-sqs-source/sqs-source-proxy.sh +++ b/connect/connect-aws-sqs-source/sqs-source-proxy.sh @@ -60,6 +60,7 @@ then # You must wait 60 seconds after deleting a queue before you can create another with the same name log "Sleeping 60 seconds" sleep 60 + aws sqs delete-queue --queue-url ${QUEUE_URL} fi set -e diff --git a/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh b/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh index 5c33c766a9..fad1e9f17b 100755 --- a/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh +++ b/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh @@ -48,6 +48,7 @@ then # You must wait 60 seconds after deleting a queue before you can create another with the same name log "Sleeping 60 seconds" sleep 60 + aws sqs delete-queue --queue-url ${QUEUE_URL} fi set -e diff --git a/connect/connect-aws-sqs-source/sqs-source.sh b/connect/connect-aws-sqs-source/sqs-source.sh index 46f52c5ec9..781ed0c006 100755 --- a/connect/connect-aws-sqs-source/sqs-source.sh +++ b/connect/connect-aws-sqs-source/sqs-source.sh @@ -60,6 +60,7 @@ then # You must wait 60 seconds after deleting a queue before you can create another with the same name log "Sleeping 60 seconds" sleep 60 + aws sqs delete-queue --queue-url ${QUEUE_URL} fi set -e diff --git a/connect/connect-jdbc-snowflake-sink/jdbc-snowflake-sink.sh b/connect/connect-jdbc-snowflake-sink/jdbc-snowflake-sink.sh index b774cae4c2..08588b97a7 100755 --- a/connect/connect-jdbc-snowflake-sink/jdbc-snowflake-sink.sh +++ b/connect/connect-jdbc-snowflake-sink/jdbc-snowflake-sink.sh @@ -98,6 +98,7 @@ GRANT USAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE ACCOUNTADMIN; GRANT CREATE TABLE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT CREATE STAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT CREATE PIPE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; +GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO ROLE ACCOUNTADMIN; EOF log "Create a Snowflake WAREHOUSE (for admin purpose as KafkaConnect is Serverless)" @@ -132,11 +133,6 @@ USE ROLE SECURITYADMIN; GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO USER $PLAYGROUND_USER; EOF -docker run --quiet --rm -i -e SNOWSQL_PWD="$SNOWFLAKE_PASSWORD" -e RSA_PUBLIC_KEY="$RSA_PUBLIC_KEY" kurron/snowsql --username $SNOWFLAKE_USERNAME -a $SNOWFLAKE_ACCOUNT_NAME << EOF -USE ROLE SYSADMIN; -GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO ROLE ACCOUNTADMIN; -EOF - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" diff --git a/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh b/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh index 8522cff156..b3ef407618 100755 --- a/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh +++ b/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh @@ -98,6 +98,7 @@ GRANT USAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE ACCOUNTADMIN; GRANT CREATE TABLE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT CREATE STAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT CREATE PIPE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; +GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO ROLE ACCOUNTADMIN; EOF log "Create a Snowflake WAREHOUSE (for admin purpose as KafkaConnect is Serverless)" @@ -132,11 +133,6 @@ USE ROLE SECURITYADMIN; GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO USER $PLAYGROUND_USER; EOF -docker run --quiet --rm -i -e SNOWSQL_PWD="$SNOWFLAKE_PASSWORD" -e RSA_PUBLIC_KEY="$RSA_PUBLIC_KEY" kurron/snowsql --username $SNOWFLAKE_USERNAME -a $SNOWFLAKE_ACCOUNT_NAME << EOF -USE ROLE SYSADMIN; -GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO ROLE ACCOUNTADMIN; -EOF - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" diff --git a/connect/connect-snowflake-sink/README.md b/connect/connect-snowflake-sink/README.md index b6936547ff..ded9bb84e3 100644 --- a/connect/connect-snowflake-sink/README.md +++ b/connect/connect-snowflake-sink/README.md @@ -66,6 +66,7 @@ GRANT USAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE ACCOUNTADMIN; GRANT CREATE TABLE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT CREATE STAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT CREATE PIPE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; +GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO ROLE ACCOUNTADMIN; EOF ``` @@ -105,11 +106,6 @@ CREATE USER $PLAYGROUND_USER USE ROLE SECURITYADMIN; GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO USER $PLAYGROUND_USER; EOF - -docker run --quiet --rm -i -e SNOWSQL_PWD="$SNOWFLAKE_PASSWORD" -e RSA_PUBLIC_KEY="$RSA_PUBLIC_KEY" kurron/snowsql --username $SNOWFLAKE_USERNAME -a $SNOWFLAKE_ACCOUNT_NAME << EOF -USE ROLE SYSADMIN; -GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO ROLE ACCOUNTADMIN; -EOF ``` Sending messages to topic `test_table` diff --git a/connect/connect-snowflake-sink/snowflake-sink-proxy.sh b/connect/connect-snowflake-sink/snowflake-sink-proxy.sh index 0bb66f1f5d..63274bcff8 100755 --- a/connect/connect-snowflake-sink/snowflake-sink-proxy.sh +++ b/connect/connect-snowflake-sink/snowflake-sink-proxy.sh @@ -80,6 +80,7 @@ GRANT USAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE ACCOUNTADMIN; GRANT CREATE TABLE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT CREATE STAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT CREATE PIPE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; +GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO ROLE ACCOUNTADMIN; EOF log "Create a Snowflake WAREHOUSE (for admin purpose as KafkaConnect is Serverless)" @@ -114,11 +115,6 @@ USE ROLE SECURITYADMIN; GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO USER $PLAYGROUND_USER; EOF -docker run --quiet --rm -i -e SNOWSQL_PWD="$SNOWFLAKE_PASSWORD" -e RSA_PUBLIC_KEY="$RSA_PUBLIC_KEY" kurron/snowsql --username $SNOWFLAKE_USERNAME -a $SNOWFLAKE_ACCOUNT_NAME << EOF -USE ROLE SYSADMIN; -GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO ROLE ACCOUNTADMIN; -EOF - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.proxy.yml" diff --git a/connect/connect-snowflake-sink/snowflake-sink-snowpipe-streaming.sh b/connect/connect-snowflake-sink/snowflake-sink-snowpipe-streaming.sh index 0fee5e6808..ede3455637 100755 --- a/connect/connect-snowflake-sink/snowflake-sink-snowpipe-streaming.sh +++ b/connect/connect-snowflake-sink/snowflake-sink-snowpipe-streaming.sh @@ -79,6 +79,7 @@ GRANT USAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE ACCOUNTADMIN; GRANT CREATE TABLE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT CREATE STAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT CREATE PIPE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; +GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO ROLE ACCOUNTADMIN; EOF log "Create a Snowflake WAREHOUSE (for admin purpose as KafkaConnect is Serverless)" @@ -113,11 +114,6 @@ USE ROLE SECURITYADMIN; GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO USER $PLAYGROUND_USER; EOF -docker run --quiet --rm -i -e SNOWSQL_PWD="$SNOWFLAKE_PASSWORD" -e RSA_PUBLIC_KEY="$RSA_PUBLIC_KEY" kurron/snowsql --username $SNOWFLAKE_USERNAME -a $SNOWFLAKE_ACCOUNT_NAME << EOF -USE ROLE SYSADMIN; -GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO ROLE ACCOUNTADMIN; -EOF - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" diff --git a/connect/connect-snowflake-sink/snowflake-sink.sh b/connect/connect-snowflake-sink/snowflake-sink.sh index 2cb60423cc..c4ad521e83 100755 --- a/connect/connect-snowflake-sink/snowflake-sink.sh +++ b/connect/connect-snowflake-sink/snowflake-sink.sh @@ -79,6 +79,7 @@ GRANT USAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE ACCOUNTADMIN; GRANT CREATE TABLE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT CREATE STAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT CREATE PIPE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; +GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO ROLE ACCOUNTADMIN; EOF log "Create a Snowflake WAREHOUSE (for admin purpose as KafkaConnect is Serverless)" @@ -113,11 +114,6 @@ USE ROLE SECURITYADMIN; GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO USER $PLAYGROUND_USER; EOF -docker run --quiet --rm -i -e SNOWSQL_PWD="$SNOWFLAKE_PASSWORD" -e RSA_PUBLIC_KEY="$RSA_PUBLIC_KEY" kurron/snowsql --username $SNOWFLAKE_USERNAME -a $SNOWFLAKE_ACCOUNT_NAME << EOF -USE ROLE SYSADMIN; -GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO ROLE ACCOUNTADMIN; -EOF - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" From fb6d389bbf72cd6f4fbf47769413b8e0bd54523a Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 16 Oct 2024 10:20:58 +0200 Subject: [PATCH 026/659] test --- ccloud/audit-log-connector/start.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ccloud/audit-log-connector/start.sh b/ccloud/audit-log-connector/start.sh index 2ca6661e9c..5813051187 100755 --- a/ccloud/audit-log-connector/start.sh +++ b/ccloud/audit-log-connector/start.sh @@ -34,6 +34,7 @@ sed -e "s|:AUDIT_LOG_CLUSTER_BOOTSTRAP_SERVERS:|$AUDIT_LOG_CLUSTER_BOOTSTRAP_SER -e "s|:AUDIT_LOG_CLUSTER_API_SECRET:|$AUDIT_LOG_CLUSTER_API_SECRET|g" \ ../../ccloud/audit-log-connector/data_audit_cluster.template > ../../ccloud/audit-log-connector/data_audit_cluster + playground start-environment --environment ccloud --docker-compose-override-file "${PWD}/docker-compose.yml" log "Creating FileStream Sink connector reading confluent-audit-log-events from the audit log cluster" From 0bab0245b729abbf0ae394a3397798c8f4effc1f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 16 Oct 2024 10:44:55 +0200 Subject: [PATCH 027/659] wip --- secrets.tar.gpg | Bin 7243 -> 7455 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/secrets.tar.gpg b/secrets.tar.gpg index f7b0b40bdb56b0309bd4f80c6fab566926149d86..7028c9f3dc57006d058be0cd6e17d6f207ab1a36 100644 GIT binary patch literal 7455 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 literal 7243 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 Z$=)BQ(|=dSh(dl8|M=t|_x~5=LrPF7{3ZYZ From bd6bf51d672321d28f73f025e41992b0aa581363 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 16 Oct 2024 12:16:26 +0200 Subject: [PATCH 028/659] Add custom connector example for Tabular Iceberg sink #5971 --- .../.gitignore | 1 + .../README.md | 22 + .../custom-iceberg-sink.sh | 198 ++++ .../data/transactions.json | 1000 +++++++++++++++++ .../docker-compose.yml | 106 ++ .../ngrok.yml | 8 + .../Untitled-checkpoint.ipynb | 6 + .../iceberg-checkpoint.ipynb | 103 ++ .../notebooks/Untitled.ipynb | 33 + .../notebooks/iceberg.ipynb | 249 ++++ .../spark/.pyiceberg.yaml | 24 + .../spark/Dockerfile | 125 +++ .../spark/create_table.py | 20 + .../spark/entrypoint.sh | 28 + .../spark/ipython/startup/00-prettytables.py | 81 ++ .../spark/ipython/startup/README | 11 + ...Introduction to the Iceberg Java API.ipynb | 469 ++++++++ .../Iceberg - Berlin Buzzwords 2023.ipynb | 361 ++++++ .../notebooks/Iceberg - Getting Started.ipynb | 509 +++++++++ .../Iceberg - Integrated Audits Demo.ipynb | 626 +++++++++++ ...- Table Maintenance Spark Procedures.ipynb | 220 ++++ .../notebooks/Iceberg - View Support.ipynb | 525 +++++++++ ...te-Audit-Publish (WAP) with Branches.ipynb | 788 +++++++++++++ .../PyIceberg - Getting Started.ipynb | 382 +++++++ .../notebooks/PyIceberg - Write support.ipynb | 251 +++++ .../spark/requirements.txt | 7 + .../spark/spark-defaults.conf | 33 + .../stop.sh | 10 + 28 files changed, 6196 insertions(+) create mode 100644 ccloud/custom-connector-connect-iceberg-sink/.gitignore create mode 100644 ccloud/custom-connector-connect-iceberg-sink/README.md create mode 100755 ccloud/custom-connector-connect-iceberg-sink/custom-iceberg-sink.sh create mode 100644 ccloud/custom-connector-connect-iceberg-sink/data/transactions.json create mode 100644 ccloud/custom-connector-connect-iceberg-sink/docker-compose.yml create mode 100644 ccloud/custom-connector-connect-iceberg-sink/ngrok.yml create mode 100644 ccloud/custom-connector-connect-iceberg-sink/notebooks/.ipynb_checkpoints/Untitled-checkpoint.ipynb create mode 100644 ccloud/custom-connector-connect-iceberg-sink/notebooks/.ipynb_checkpoints/iceberg-checkpoint.ipynb create mode 100644 ccloud/custom-connector-connect-iceberg-sink/notebooks/Untitled.ipynb create mode 100644 ccloud/custom-connector-connect-iceberg-sink/notebooks/iceberg.ipynb create mode 100644 ccloud/custom-connector-connect-iceberg-sink/spark/.pyiceberg.yaml create mode 100644 ccloud/custom-connector-connect-iceberg-sink/spark/Dockerfile create mode 100644 ccloud/custom-connector-connect-iceberg-sink/spark/create_table.py create mode 100755 ccloud/custom-connector-connect-iceberg-sink/spark/entrypoint.sh create mode 100644 ccloud/custom-connector-connect-iceberg-sink/spark/ipython/startup/00-prettytables.py create mode 100644 ccloud/custom-connector-connect-iceberg-sink/spark/ipython/startup/README create mode 100644 ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - An Introduction to the Iceberg Java API.ipynb create mode 100644 ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Berlin Buzzwords 2023.ipynb create mode 100644 ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Getting Started.ipynb create mode 100644 ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Integrated Audits Demo.ipynb create mode 100644 ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Table Maintenance Spark Procedures.ipynb create mode 100644 ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - View Support.ipynb create mode 100644 ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Write-Audit-Publish (WAP) with Branches.ipynb create mode 100644 ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/PyIceberg - Getting Started.ipynb create mode 100644 ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/PyIceberg - Write support.ipynb create mode 100644 ccloud/custom-connector-connect-iceberg-sink/spark/requirements.txt create mode 100755 ccloud/custom-connector-connect-iceberg-sink/spark/spark-defaults.conf create mode 100755 ccloud/custom-connector-connect-iceberg-sink/stop.sh diff --git a/ccloud/custom-connector-connect-iceberg-sink/.gitignore b/ccloud/custom-connector-connect-iceberg-sink/.gitignore new file mode 100644 index 0000000000..6f66c74b0e --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/.gitignore @@ -0,0 +1 @@ +*.zip \ No newline at end of file diff --git a/ccloud/custom-connector-connect-iceberg-sink/README.md b/ccloud/custom-connector-connect-iceberg-sink/README.md new file mode 100644 index 0000000000..5a02ecf00d --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/README.md @@ -0,0 +1,22 @@ +# Custom Connector Apache Iceberg Sink Connector connector + + + +## Objective + +Quickly test [Apache Iceberg Sink Connector](https://github.com/tabular-io/iceberg-kafka-connect?tab=readme-ov-file) connector. + + + + +## How to run + +Simply run: + +``` +$ just use command +``` + +You can open the jupyter lab at http://localhost:8888/lab/tree/notebooks and use the sample notebook to query the table + +Refer to docker-spark-iceberg to check more details about it \ No newline at end of file diff --git a/ccloud/custom-connector-connect-iceberg-sink/custom-iceberg-sink.sh b/ccloud/custom-connector-connect-iceberg-sink/custom-iceberg-sink.sh new file mode 100755 index 0000000000..75fc27de5d --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/custom-iceberg-sink.sh @@ -0,0 +1,198 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +if [ ! -f tabular-iceberg-kafka-connect-0.6.19.zip ] +then + log "Downloading tabular-iceberg-kafka-connect-0.6.19.zip from confluent hub" + wget -q https://d2p6pa21dvn84.cloudfront.net/api/plugins/tabular/iceberg-kafka-connect/versions/0.6.19/tabular-iceberg-kafka-connect-0.6.19.zip +fi + +plugin_name="pg_${USER}_tabular_iceberg_sink_0_6_19" + +set +e +for row in $(confluent connect custom-plugin list --output json | jq -r '.[] | @base64'); do + _jq() { + echo ${row} | base64 -d | jq -r ${1} + } + + id=$(echo $(_jq '.id')) + name=$(echo $(_jq '.name')) + + if [[ "$name" = "$plugin_name" ]] + then + log "deleting plugin $id ($name)" + confluent connect custom-plugin delete $id --force + fi +done +set -e + +log "Uploading custom plugin $plugin_name" +confluent connect custom-plugin create $plugin_name --plugin-file tabular-iceberg-kafka-connect-0.6.19.zip --connector-class io.tabular.iceberg.connect.IcebergSinkConnector --connector-type SINK --sensitive-properties "iceberg.kafka.sasl.jaas.config" +ret=$? + +function cleanup_resources { + log "Do you want to delete the custom plugin $plugin_name ($plugin_id) and custom connector $connector_name ?" + check_if_continue + + playground connector delete --connector $connector_name + confluent connect custom-plugin delete $plugin_id --force +} +trap cleanup_resources EXIT + +set -e +if [ $ret -eq 0 ] +then + found=0 + set +e + for row in $(confluent connect custom-plugin list --output json | jq -r '.[] | @base64'); do + _jq() { + echo ${row} | base64 -d | jq -r ${1} + } + + id=$(echo $(_jq '.id')) + name=$(echo $(_jq '.name')) + + if [[ "$name" = "$plugin_name" ]] + then + plugin_id="$id" + log "custom plugin $plugin_name ($plugin_id) was successfully uploaded!" + found=1 + break + fi + done +else + logerror "❌ command failed with error code $ret!" + exit 1 +fi +set -e +if [ $found -eq 0 ] +then + logerror "❌ plugin could not be uploaded !" + exit 1 +fi + +NGROK_AUTH_TOKEN=${NGROK_AUTH_TOKEN:-$1} + +display_ngrok_warning + +bootstrap_ccloud_environment + + + +set +e +playground topic delete --topic payments +playground topic delete --topic control-iceberg + +sleep 3 + +playground topic create --topic control-iceberg +set -e + +docker compose build +docker compose down -v --remove-orphans +docker compose up -d --quiet-pull + +sleep 30 + +log "Waiting for ngrok to start" +while true +do + container_id=$(docker ps -q -f name=ngrok) + if [ -n "$container_id" ] + then + status=$(docker inspect --format '{{.State.Status}}' $container_id) + if [ "$status" = "running" ] + then + log "Getting ngrok hostname and port" + NGROK_URL=$(curl --silent http://127.0.0.1:4040/api/tunnels | jq -r '.tunnels[0].public_url') + NGROK_HOSTNAME=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 1) + NGROK_PORT=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 2) + + NGROK_URL2=$(curl --silent http://127.0.0.1:4040/api/tunnels | jq -r '.tunnels[1].public_url') + NGROK_HOSTNAME2=$(echo $NGROK_URL2 | cut -d "/" -f3 | cut -d ":" -f 1) + NGROK_PORT2=$(echo $NGROK_URL2 | cut -d "/" -f3 | cut -d ":" -f 2) + + if ! [[ $NGROK_PORT =~ ^[0-9]+$ ]] + then + log "NGROK_PORT is not a valid number, keep retrying..." + continue + else + break + fi + fi + fi + log "Waiting for container ngrok to start..." + sleep 5 +done + + +log "Sending messages to topic payments" +playground topic produce -t payments --nb-messages $(wc -l <"../../ccloud/custom-connector-connect-iceberg-sink/data/transactions.json") --value ../../ccloud/custom-connector-connect-iceberg-sink/data/transactions.json + +connector_name="ICEBERG_SINK_CUSTOM_$USER" +set +e +log "Deleting confluent cloud custom connector $connector_name, it might fail..." +playground connector delete --connector $connector_name +set -e + + +log "Creating Iceberg sink connector" +playground connector create-or-update --connector $connector_name << EOF +{ + "confluent.connector.type": "CUSTOM", + "confluent.custom.plugin.id": "$plugin_id", + "confluent.custom.connection.endpoints": "$NGROK_HOSTNAME:$NGROK_PORT:TCP;$NGROK_HOSTNAME2:$NGROK_PORT2:TCP", + + "kafka.api.key": "$CLOUD_KEY", + "kafka.api.secret": "$CLOUD_SECRET", + "name": "$connector_name", + "tasks.max": "1", + "topics": "payments", + "connector.class": "io.tabular.iceberg.connect.IcebergSinkConnector", + + "iceberg.catalog.s3.endpoint": "http://$NGROK_HOSTNAME2:$NGROK_PORT2", + "iceberg.catalog.s3.secret-access-key": "minioadmin", + "iceberg.catalog.s3.access-key-id": "minioadmin", + "iceberg.catalog.s3.path-style-access": "true", + "iceberg.catalog.uri": "http://$NGROK_HOSTNAME:$NGROK_PORT", + "iceberg.catalog.warehouse": "s3://warehouse/", + "iceberg.catalog.client.region": "eu-west-1", + "iceberg.catalog.type": "rest", + "iceberg.control.commit.interval-ms": "1000", + "iceberg.tables.auto-create-enabled": "true", + "iceberg.tables": "orders.payments", + "iceberg.kafka.sasl.jaas.config":"org.apache.kafka.common.security.plain.PlainLoginModule required username=\"$CLOUD_KEY\" password=\"$CLOUD_SECRET\";", + "value.converter.schemas.enable": "false", + "value.converter": "org.apache.kafka.connect.json.JsonConverter", + "key.converter": "org.apache.kafka.connect.storage.StringConverter", + "schemas.enable": "false", + + "errors.tolerance": "all", + "errors.deadletterqueue.topic.name": "dlq", + "errors.deadletterqueue.topic.replication.factor": "3", + "errors.deadletterqueue.context.headers.enable": "true", + "errors.log.enable": "true", + "errors.log.include.messages": "true" +} +EOF + +sleep 30 + +playground connector show-lag --max-wait 300 + +if [ -z "$GITHUB_RUN_NUMBER" ] +then + # doesn't work on github actions + # not running with github actions + log "You can open the jupyter lab at http://localhost:8888/lab/tree/notebooks and use the sample notebook in notebooks/iceberg.ipynb to query the table" + + log "Verify data is in Iceberg" + docker exec -i spark-iceberg spark-sql << EOF +SELECT * +FROM orders.payments +LIMIT 10; +EOF +fi \ No newline at end of file diff --git a/ccloud/custom-connector-connect-iceberg-sink/data/transactions.json b/ccloud/custom-connector-connect-iceberg-sink/data/transactions.json new file mode 100644 index 0000000000..9508bdfa07 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/data/transactions.json @@ -0,0 +1,1000 @@ +{"id": "99e7a457-c86d-47de-824e-dcb90865a388", "type": "debit", "created_at": "2022-09-13T00:00:00", "document": "80", "payer": "Joyce Wimberly", "amount": 3814} +{"id": "90c2a935-26e7-4cc6-863c-c1c169348169", "type": "credit", "created_at": "2022-06-12T00:00:00", "document": "85", "payer": "Susan Wolcott", "amount": 1917} +{"id": "7207dcf9-43b8-4d5b-854a-fed96d1e896f", "type": "bank_slip", "created_at": "2022-05-27T00:00:00", "document": "4", "payer": "Marcia Griffin", "amount": 4265} +{"id": "22a6c526-b758-4035-91a9-c77a3f7dc9ed", "type": "debit", "created_at": "2022-06-05T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 3012} +{"id": "30c3fb33-8d78-4de9-9291-a3388c7b6014", "type": "credit", "created_at": "2022-11-06T00:00:00", "document": "48", "payer": "Lori Carter", "amount": 1868} +{"id": "4ec089f8-d9b2-4bac-99ea-7efbf3ca67e4", "type": "bank_slip", "created_at": "2022-06-26T00:00:00", "document": "83", "payer": "Filomena Suther", "amount": 4596} +{"id": "4545f835-10ba-4033-b63a-118116d3d61b", "type": "bank_slip", "created_at": "2022-09-04T00:00:00", "document": "34", "payer": "Sheila Ellard", "amount": 5024} +{"id": "99a7b931-7d02-4f00-91bb-59e875bcbc76", "type": "credit", "created_at": "2022-08-15T00:00:00", "document": "7", "payer": "Maria Bonney", "amount": 9018} +{"id": "5c95505b-35c5-4f35-a64b-d415708ab707", "type": "bank_slip", "created_at": "2022-03-27T00:00:00", "document": "40", "payer": "Charles Malik", "amount": 8567} +{"id": "cc402b3f-189a-4251-85c7-f91c2bab7fa7", "type": "credit", "created_at": "2022-01-22T00:00:00", "document": "54", "payer": "Carmela Ho", "amount": 867} +{"id": "a1988618-e541-4ebd-b436-aa0e32a7983d", "type": "credit", "created_at": "2022-08-19T00:00:00", "document": "35", "payer": "Maggie Auten", "amount": 6258} +{"id": "5fe6df9c-4aa2-4f58-89e3-ee3a42013483", "type": "credit", "created_at": "2022-10-04T00:00:00", "document": "83", "payer": "Filomena Suther", "amount": 6312} +{"id": "54a272ac-1dc5-4f30-9ddd-27069b03b099", "type": "debit", "created_at": "2022-02-12T00:00:00", "document": "83", "payer": "Filomena Suther", "amount": 4057} +{"id": "a75766b2-d8aa-4f38-8533-1ee331b96a16", "type": "credit", "created_at": "2022-03-31T00:00:00", "document": "12", "payer": "Susan Woodward", "amount": 503} +{"id": "7ce9e050-0d47-4fb9-9eba-185f22200503", "type": "bank_slip", "created_at": "2022-03-02T00:00:00", "document": "73", "payer": "Fe Bartkowiak", "amount": 7139} +{"id": "a6d8e76f-5c90-41c1-b98c-aa075bc41dbf", "type": "debit", "created_at": "2022-08-26T00:00:00", "document": "75", "payer": "Edie Callam", "amount": 715} +{"id": "e83474f8-9573-4115-be5c-eb7feb3a4a46", "type": "credit", "created_at": "2022-07-07T00:00:00", "document": "25", "payer": "Calvin Reid", "amount": 7579} +{"id": "324f338b-0be4-450c-9a6d-547978a0ef00", "type": "bank_slip", "created_at": "2022-03-21T00:00:00", "document": "22", "payer": "Noemi Mcintyre", "amount": 9523} +{"id": "c551be48-7734-49cb-b3a1-5ab65ba1d7fc", "type": "bank_slip", "created_at": "2022-11-17T00:00:00", "document": "48", "payer": "Lori Carter", "amount": 6968} +{"id": "79388493-61dd-4164-8e76-1cd662bae296", "type": "credit", "created_at": "2022-12-09T00:00:00", "document": "10", "payer": "Emanuel Robinson", "amount": 2732} +{"id": "c8936c42-2f02-415d-84b8-e478a2a061e3", "type": "bank_slip", "created_at": "2022-09-14T00:00:00", "document": "44", "payer": "Kevin Parry", "amount": 1055} +{"id": "52704039-8895-4da7-9ac2-88fb829444fc", "type": "credit", "created_at": "2022-07-05T00:00:00", "document": "98", "payer": "Elma Snapp", "amount": 1678} +{"id": "bbbeabcf-585d-41d5-9621-ca10ec1c624b", "type": "debit", "created_at": "2022-09-12T00:00:00", "document": "35", "payer": "Maggie Auten", "amount": 5950} +{"id": "36253bb1-245b-4472-8939-aea1316bc627", "type": "bank_slip", "created_at": "2022-12-20T00:00:00", "document": "3", "payer": "Conrad Hardin", "amount": 292} +{"id": "24550eef-12d4-422e-b0ce-6c87e1309bbd", "type": "debit", "created_at": "2022-07-20T00:00:00", "document": "39", "payer": "Brendan Pease", "amount": 5827} +{"id": "0677ce3b-9164-4263-9e9d-0e3a9bf830f5", "type": "debit", "created_at": "2022-03-31T00:00:00", "document": "22", "payer": "Noemi Mcintyre", "amount": 5527} +{"id": "c4f6da0a-e304-4360-93c0-a6c7e0f1d80e", "type": "bank_slip", "created_at": "2022-09-10T00:00:00", "document": "56", "payer": "Katherine Alexander", "amount": 5092} +{"id": "3d58b6f0-3560-47da-ad19-d4a2cfe4ee18", "type": "bank_slip", "created_at": "2022-12-11T00:00:00", "document": "99", "payer": "Mark Seidel", "amount": 3059} +{"id": "a9e9fd27-47f1-4688-b51d-e288f8cd80ce", "type": "bank_slip", "created_at": "2022-12-30T00:00:00", "document": "62", "payer": "Latasha Rubio", "amount": 9794} +{"id": "b5c400f5-da44-499f-9983-1aefcb0ba109", "type": "credit", "created_at": "2022-03-16T00:00:00", "document": "14", "payer": "Eleanore Hocutt", "amount": 4431} +{"id": "5c5ed237-b7a0-4b8f-afa7-d36ce088e6ec", "type": "credit", "created_at": "2022-01-03T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 5339} +{"id": "8e4910f3-f2bb-45fa-bf85-dc6811468038", "type": "bank_slip", "created_at": "2022-07-20T00:00:00", "document": "35", "payer": "Maggie Auten", "amount": 7020} +{"id": "a5a172ba-0ef4-4cba-a8d1-ea2580cde2d2", "type": "bank_slip", "created_at": "2022-04-10T00:00:00", "document": "26", "payer": "Robert Krupp", "amount": 5570} +{"id": "5b58f85a-e603-4d3c-be04-f3b7a16337fd", "type": "bank_slip", "created_at": "2022-11-16T00:00:00", "document": "15", "payer": "James Blomdahl", "amount": 6044} +{"id": "d82ad64e-98cc-4bac-a2c2-a230418003ee", "type": "debit", "created_at": "2022-12-20T00:00:00", "document": "15", "payer": "James Blomdahl", "amount": 7065} +{"id": "95d59330-318a-4b9c-9060-dd99cd003a81", "type": "credit", "created_at": "2022-07-09T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 993} +{"id": "dd2893ad-60c0-4f1d-ac9c-fbc69e706e42", "type": "bank_slip", "created_at": "2022-04-10T00:00:00", "document": "25", "payer": "Calvin Reid", "amount": 9482} +{"id": "0bb3d04b-fa41-4975-8d23-362bbd85613b", "type": "credit", "created_at": "2022-12-23T00:00:00", "document": "67", "payer": "Wiley Goetz", "amount": 9160} +{"id": "db8cee5e-7847-4f28-be86-0b65f3c13ce7", "type": "credit", "created_at": "2022-09-12T00:00:00", "document": "7", "payer": "Maria Bonney", "amount": 7484} +{"id": "081294a6-b915-4762-8624-38a189f75f0a", "type": "debit", "created_at": "2022-09-15T00:00:00", "document": "6", "payer": "John Dickerson", "amount": 2754} +{"id": "384f6f04-a518-46a8-bda9-e9d8148982d3", "type": "bank_slip", "created_at": "2022-11-14T00:00:00", "document": "58", "payer": "Erin Rhoads", "amount": 1925} +{"id": "562c496d-4036-4e15-ab58-e42cc3b65623", "type": "bank_slip", "created_at": "2022-12-06T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 2427} +{"id": "dabebe12-4387-446d-b5ef-0e573e2d225c", "type": "credit", "created_at": "2022-03-16T00:00:00", "document": "89", "payer": "Antonio Cooley", "amount": 8012} +{"id": "c261795c-2ab9-41c9-b46a-fe186d24a087", "type": "credit", "created_at": "2022-03-31T00:00:00", "document": "26", "payer": "Robert Krupp", "amount": 5235} +{"id": "b8be58a2-70a2-4473-948a-bea361970875", "type": "credit", "created_at": "2022-06-07T00:00:00", "document": "84", "payer": "Rick Reid", "amount": 8557} +{"id": "95420e7a-2e6e-4c1b-a782-d39fd02de769", "type": "debit", "created_at": "2022-08-08T00:00:00", "document": "68", "payer": "Pauline Marcum", "amount": 3724} +{"id": "a4982461-12e5-4e31-93e7-0bc0c9a633e6", "type": "credit", "created_at": "2022-12-02T00:00:00", "document": "60", "payer": "Rachel York", "amount": 2036} +{"id": "592d21fa-c56f-44bb-bd58-0ed415f6ab05", "type": "credit", "created_at": "2022-12-20T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 7291} +{"id": "33fe6a56-1f47-4288-9775-0656f3991aed", "type": "debit", "created_at": "2022-10-30T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 8445} +{"id": "4e5fc495-dde8-4f13-9bb2-2390559ed963", "type": "bank_slip", "created_at": "2022-01-21T00:00:00", "document": "50", "payer": "Karen Lewis", "amount": 1505} +{"id": "61a606dd-9f4b-42a2-a95d-1f18f0ed753d", "type": "credit", "created_at": "2022-04-02T00:00:00", "document": "34", "payer": "Sheila Ellard", "amount": 1933} +{"id": "5b78dfe7-ee5b-45f6-bb35-c1be27c47196", "type": "debit", "created_at": "2022-06-30T00:00:00", "document": "69", "payer": "Mark Evans", "amount": 2966} +{"id": "e29cd169-b384-45df-8509-02c9020b4cc3", "type": "credit", "created_at": "2022-09-15T00:00:00", "document": "84", "payer": "Rick Reid", "amount": 1620} +{"id": "f0eac1de-77cf-4262-88dd-13581de016e7", "type": "debit", "created_at": "2022-08-01T00:00:00", "document": "32", "payer": "Barbara Harris", "amount": 5748} +{"id": "d5af09db-96c1-46c6-aa24-ff1fb11c1e97", "type": "debit", "created_at": "2022-07-09T00:00:00", "document": "6", "payer": "John Dickerson", "amount": 773} +{"id": "9fa70049-357d-4807-8b55-4c7ebc017cfc", "type": "bank_slip", "created_at": "2022-06-14T00:00:00", "document": "18", "payer": "Armida Kostrzewa", "amount": 7525} +{"id": "f49eda9c-2e23-4d8e-85ba-770485597026", "type": "debit", "created_at": "2022-04-19T00:00:00", "document": "4", "payer": "Marcia Griffin", "amount": 2235} +{"id": "925e1bee-431f-4444-b465-f02c5fd54ead", "type": "bank_slip", "created_at": "2022-07-02T00:00:00", "document": "41", "payer": "Tamera Boone", "amount": 3235} +{"id": "32d9daa8-70d0-4fe0-bf8a-1ce7dafa739e", "type": "bank_slip", "created_at": "2022-10-07T00:00:00", "document": "10", "payer": "Emanuel Robinson", "amount": 7260} +{"id": "3557642d-32b4-4ca1-81c7-401a8647c0af", "type": "debit", "created_at": "2022-09-19T00:00:00", "document": "80", "payer": "Joyce Wimberly", "amount": 6291} +{"id": "afd44e3d-6c7f-43d5-995b-7ce141aff9ec", "type": "credit", "created_at": "2022-03-28T00:00:00", "document": "92", "payer": "Amber Hudson", "amount": 1316} +{"id": "fd1709be-12fa-4357-b034-42c1b29921b0", "type": "credit", "created_at": "2022-11-17T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 996} +{"id": "127cc5c1-1e93-44ac-adbf-6ee7c0c98eb1", "type": "debit", "created_at": "2022-10-08T00:00:00", "document": "8", "payer": "Nicky Jones", "amount": 7110} +{"id": "7f2b1430-07db-4011-b2dc-212ac37fb092", "type": "bank_slip", "created_at": "2022-01-04T00:00:00", "document": "40", "payer": "Charles Malik", "amount": 4836} +{"id": "fab4be9d-95bf-4f26-b051-2072cef7a8c3", "type": "debit", "created_at": "2023-01-01T00:00:00", "document": "18", "payer": "Armida Kostrzewa", "amount": 3420} +{"id": "056ffd43-ddf9-4c62-a985-63ef90646bac", "type": "credit", "created_at": "2022-04-10T00:00:00", "document": "45", "payer": "Shanita Bergesen", "amount": 3488} +{"id": "3b024976-c89d-4f1f-a649-860be2a1a2a3", "type": "credit", "created_at": "2022-08-30T00:00:00", "document": "90", "payer": "Michael Griffin", "amount": 6451} +{"id": "0f4f0163-9d94-43f6-bf08-6231fc554d99", "type": "bank_slip", "created_at": "2022-01-06T00:00:00", "document": "21", "payer": "Richard Duckett", "amount": 9156} +{"id": "e51497ba-d05d-4f95-82a5-20ca9b1ed7ee", "type": "bank_slip", "created_at": "2022-07-01T00:00:00", "document": "22", "payer": "Noemi Mcintyre", "amount": 1852} +{"id": "304915df-5c70-4ea4-ba22-ca5207daf142", "type": "bank_slip", "created_at": "2022-09-28T00:00:00", "document": "55", "payer": "Ashley Beauchesne", "amount": 7563} +{"id": "546072fd-4cfc-4e60-a511-80e6c46cb168", "type": "credit", "created_at": "2022-01-21T00:00:00", "document": "44", "payer": "Kevin Parry", "amount": 9313} +{"id": "f376ae8a-8448-4e40-ad61-e80308a7cd14", "type": "credit", "created_at": "2022-08-14T00:00:00", "document": "49", "payer": "Richard Isbell", "amount": 8899} +{"id": "284403bc-efe9-4517-83ab-81009c3ec163", "type": "credit", "created_at": "2022-08-25T00:00:00", "document": "76", "payer": "Megan Wallace", "amount": 9225} +{"id": "bc74fc02-9843-4163-aa57-d9b4e74f8c5d", "type": "debit", "created_at": "2022-04-20T00:00:00", "document": "42", "payer": "Carolyn Ponyah", "amount": 2558} +{"id": "cdb2e945-26cb-492d-a148-a6cf25b6fe79", "type": "bank_slip", "created_at": "2022-08-16T00:00:00", "document": "84", "payer": "Rick Reid", "amount": 9617} +{"id": "90145849-e9eb-4bdc-bb5a-4d6aa0af35af", "type": "bank_slip", "created_at": "2022-08-21T00:00:00", "document": "57", "payer": "David Landry", "amount": 7783} +{"id": "a8c2ccd2-38d5-4fde-8e01-478eee1dbf10", "type": "bank_slip", "created_at": "2022-02-25T00:00:00", "document": "12", "payer": "Susan Woodward", "amount": 847} +{"id": "7788a6bd-a6e9-4920-8700-c627f092dd29", "type": "debit", "created_at": "2022-11-16T00:00:00", "document": "96", "payer": "Earl Morgan", "amount": 1759} +{"id": "cd028c09-cbee-4216-92d3-098c8749f4dd", "type": "bank_slip", "created_at": "2022-06-29T00:00:00", "document": "82", "payer": "Juan Federico", "amount": 1920} +{"id": "74397e97-e0bb-4fdd-896b-cbf5618942c6", "type": "debit", "created_at": "2022-11-20T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 7167} +{"id": "0aab19dc-f739-4f86-a917-81f8ee7cfabb", "type": "bank_slip", "created_at": "2022-02-03T00:00:00", "document": "83", "payer": "Filomena Suther", "amount": 6138} +{"id": "51355c97-e079-4286-9458-6bd0d4998e52", "type": "credit", "created_at": "2022-07-11T00:00:00", "document": "35", "payer": "Maggie Auten", "amount": 9095} +{"id": "f20508d6-de40-4489-955a-3200dd176c00", "type": "bank_slip", "created_at": "2022-03-24T00:00:00", "document": "88", "payer": "Gabrielle Santoyo", "amount": 3167} +{"id": "4376f178-dc1e-47e0-b5f3-c469cdb6ef7d", "type": "bank_slip", "created_at": "2022-09-25T00:00:00", "document": "85", "payer": "Susan Wolcott", "amount": 3028} +{"id": "00ef44ac-c357-4016-b79a-d7e0b2576f8f", "type": "debit", "created_at": "2022-10-22T00:00:00", "document": "42", "payer": "Carolyn Ponyah", "amount": 4051} +{"id": "cb116ac6-9b1a-45c0-89c9-67cb9bc74329", "type": "credit", "created_at": "2022-04-15T00:00:00", "document": "51", "payer": "Kenneth Stewart", "amount": 8215} +{"id": "10c3245a-bf10-4796-9989-947da6f058c4", "type": "credit", "created_at": "2022-03-29T00:00:00", "document": "80", "payer": "Joyce Wimberly", "amount": 3934} +{"id": "cc70cd4f-c32e-4b0d-8b20-b37b4c6df38c", "type": "credit", "created_at": "2022-09-21T00:00:00", "document": "73", "payer": "Fe Bartkowiak", "amount": 1072} +{"id": "9cae835b-2d91-4e35-81fd-f90e90517399", "type": "bank_slip", "created_at": "2022-04-16T00:00:00", "document": "73", "payer": "Fe Bartkowiak", "amount": 6318} +{"id": "a9608f38-fe7c-4d32-b836-60a8dca67f0a", "type": "debit", "created_at": "2022-11-09T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 1348} +{"id": "6655b159-6db6-4fe2-9666-5307657f38e5", "type": "bank_slip", "created_at": "2022-02-08T00:00:00", "document": "44", "payer": "Kevin Parry", "amount": 1861} +{"id": "d3b3bf58-d8bf-474f-83fa-41401ec28a1b", "type": "debit", "created_at": "2022-03-01T00:00:00", "document": "51", "payer": "Kenneth Stewart", "amount": 2600} +{"id": "466b9a06-4a32-4041-b81a-85d5d379bbee", "type": "bank_slip", "created_at": "2022-11-10T00:00:00", "document": "4", "payer": "Marcia Griffin", "amount": 9164} +{"id": "75b74907-a83a-4e4c-b3b9-ec3fd0eb5132", "type": "debit", "created_at": "2022-12-25T00:00:00", "document": "47", "payer": "Dustin Diller", "amount": 7691} +{"id": "d1bd35d6-b6b6-4a24-b119-43d9f8724f25", "type": "debit", "created_at": "2022-12-01T00:00:00", "document": "29", "payer": "Timothy Short", "amount": 3710} +{"id": "c80169ac-1a8c-4458-a786-1a6e71428da7", "type": "bank_slip", "created_at": "2022-08-12T00:00:00", "document": "86", "payer": "Robert Kraft", "amount": 8365} +{"id": "1ae27a72-b395-4cab-80c7-a93cc3a91e19", "type": "credit", "created_at": "2022-05-24T00:00:00", "document": "76", "payer": "Megan Wallace", "amount": 6474} +{"id": "d4dce8a1-7936-4072-a905-73017a3f2791", "type": "debit", "created_at": "2022-11-13T00:00:00", "document": "49", "payer": "Richard Isbell", "amount": 6402} +{"id": "f0441736-d940-47a5-b81d-2384e123a723", "type": "credit", "created_at": "2022-01-23T00:00:00", "document": "87", "payer": "Emily Cockerill", "amount": 7239} +{"id": "24e3fcfa-f8a9-4083-a49c-a3fe1b6cc8c7", "type": "bank_slip", "created_at": "2022-10-30T00:00:00", "document": "29", "payer": "Timothy Short", "amount": 2031} +{"id": "6c1649ce-1d1e-4f6e-8137-12ff3b1c957d", "type": "bank_slip", "created_at": "2022-11-09T00:00:00", "document": "82", "payer": "Juan Federico", "amount": 9865} +{"id": "aad32abb-dd18-4b59-a47e-afeb0f7ed2ae", "type": "bank_slip", "created_at": "2022-10-06T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 3075} +{"id": "c0e81e7d-d0f9-4663-8fd7-756cf95052b3", "type": "credit", "created_at": "2022-07-23T00:00:00", "document": "18", "payer": "Armida Kostrzewa", "amount": 660} +{"id": "bf2c0924-c49a-4cc5-a236-c5400a23270d", "type": "credit", "created_at": "2022-12-20T00:00:00", "document": "66", "payer": "Kimberly Scott", "amount": 8966} +{"id": "c2809020-67b5-4006-930a-c992764a5740", "type": "credit", "created_at": "2022-12-18T00:00:00", "document": "92", "payer": "Amber Hudson", "amount": 1868} +{"id": "1bfa7e14-bbd2-41de-b8ba-b1a4bfbe88ef", "type": "debit", "created_at": "2022-05-24T00:00:00", "document": "27", "payer": "Devin Felt", "amount": 333} +{"id": "3f193d33-f31b-4f52-95df-985335eb33bd", "type": "bank_slip", "created_at": "2022-12-25T00:00:00", "document": "83", "payer": "Filomena Suther", "amount": 9591} +{"id": "e80bab37-6be1-4b5b-84c1-f41634924492", "type": "credit", "created_at": "2022-05-08T00:00:00", "document": "96", "payer": "Earl Morgan", "amount": 14} +{"id": "c298ba67-cb71-4e09-982d-82d60f066521", "type": "credit", "created_at": "2022-10-04T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 5648} +{"id": "a5ef3b0c-00a3-43df-b5b5-f55e04ffb973", "type": "bank_slip", "created_at": "2022-01-03T00:00:00", "document": "50", "payer": "Karen Lewis", "amount": 9652} +{"id": "b49f7334-444d-427a-ae75-924cf9117d48", "type": "debit", "created_at": "2022-12-20T00:00:00", "document": "43", "payer": "Gary Jensen", "amount": 8169} +{"id": "da2afb6b-0501-40b1-b1ba-6f4488142f82", "type": "debit", "created_at": "2022-05-01T00:00:00", "document": "19", "payer": "Patrick Monson", "amount": 7492} +{"id": "e1190d99-d0cc-44b9-8501-a2cf4e0d0c28", "type": "bank_slip", "created_at": "2022-04-21T00:00:00", "document": "51", "payer": "Kenneth Stewart", "amount": 1114} +{"id": "29b670cc-81b2-4097-b49e-8947fc047075", "type": "debit", "created_at": "2022-03-01T00:00:00", "document": "77", "payer": "Michael Fultz", "amount": 4458} +{"id": "78d09ef7-d36f-4884-8d97-e2f4492ab002", "type": "credit", "created_at": "2022-09-08T00:00:00", "document": "76", "payer": "Megan Wallace", "amount": 482} +{"id": "0e366f1c-c071-4c68-bd30-9ed096be7d98", "type": "bank_slip", "created_at": "2022-01-05T00:00:00", "document": "54", "payer": "Carmela Ho", "amount": 5132} +{"id": "64c49c95-70bf-41b7-ad5c-bdc5a0bdf80f", "type": "bank_slip", "created_at": "2022-08-25T00:00:00", "document": "40", "payer": "Charles Malik", "amount": 236} +{"id": "b31c5069-ded7-4de5-8c33-6abd72833f9d", "type": "credit", "created_at": "2022-11-17T00:00:00", "document": "88", "payer": "Gabrielle Santoyo", "amount": 469} +{"id": "6cea1aeb-342f-4083-bd8e-13b72a7c48e9", "type": "bank_slip", "created_at": "2022-08-01T00:00:00", "document": "78", "payer": "Paul debiten", "amount": 5615} +{"id": "2138b587-52de-46e0-9999-ee95de3e2418", "type": "bank_slip", "created_at": "2022-10-28T00:00:00", "document": "35", "payer": "Maggie Auten", "amount": 3256} +{"id": "480fd45d-2fc8-43f3-b3f6-4d23f4359403", "type": "bank_slip", "created_at": "2022-09-18T00:00:00", "document": "31", "payer": "Ridebito Little", "amount": 7032} +{"id": "257eb230-2593-4b91-87fb-aef944c4e219", "type": "credit", "created_at": "2022-07-17T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 3825} +{"id": "1e47d973-ef18-40f1-acff-8f123a779a36", "type": "debit", "created_at": "2022-06-06T00:00:00", "document": "96", "payer": "Earl Morgan", "amount": 3177} +{"id": "034f98ab-3935-4b13-936f-4d95a81bafb1", "type": "bank_slip", "created_at": "2022-04-06T00:00:00", "document": "90", "payer": "Michael Griffin", "amount": 9150} +{"id": "8c410f32-5e24-418b-99ef-4a5c07a18264", "type": "credit", "created_at": "2022-12-12T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 9551} +{"id": "5ad18ff0-187b-4199-9283-40d09873e015", "type": "bank_slip", "created_at": "2022-08-22T00:00:00", "document": "50", "payer": "Karen Lewis", "amount": 9184} +{"id": "8324dace-9740-4bac-aa89-5e87aefb22db", "type": "debit", "created_at": "2022-08-07T00:00:00", "document": "34", "payer": "Sheila Ellard", "amount": 9378} +{"id": "e08858cd-a92d-4bd2-bf90-aefccb5f6d13", "type": "bank_slip", "created_at": "2022-05-24T00:00:00", "document": "92", "payer": "Amber Hudson", "amount": 1934} +{"id": "4ade39c7-06fc-4bde-a561-b22d5081cec1", "type": "credit", "created_at": "2022-03-13T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 2909} +{"id": "44484eca-18b1-416e-a31b-5722178f2c5b", "type": "debit", "created_at": "2022-11-17T00:00:00", "document": "92", "payer": "Amber Hudson", "amount": 3132} +{"id": "765ae679-6b07-4b0a-a42a-961ca076abc1", "type": "bank_slip", "created_at": "2022-11-20T00:00:00", "document": "58", "payer": "Erin Rhoads", "amount": 9715} +{"id": "6a2afd30-ca61-4b89-a87e-5bd977d83ea3", "type": "credit", "created_at": "2022-04-11T00:00:00", "document": "2", "payer": "Ella Tatum", "amount": 1529} +{"id": "debfb244-b413-407f-bc1c-15d080342861", "type": "credit", "created_at": "2022-04-23T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 5081} +{"id": "ef12d207-50b6-46f3-8cfc-32ee79236cc9", "type": "credit", "created_at": "2022-03-23T00:00:00", "document": "71", "payer": "Florence Henderson", "amount": 9221} +{"id": "8f466d96-b38c-407f-ac2d-7e8441157c1f", "type": "bank_slip", "created_at": "2022-11-08T00:00:00", "document": "92", "payer": "Amber Hudson", "amount": 2346} +{"id": "dd4b0ab9-8e4d-4097-b62a-13f070b47395", "type": "bank_slip", "created_at": "2022-09-30T00:00:00", "document": "22", "payer": "Noemi Mcintyre", "amount": 9986} +{"id": "1a88f7c2-1091-4f12-a301-e295499d59b3", "type": "credit", "created_at": "2022-06-23T00:00:00", "document": "80", "payer": "Joyce Wimberly", "amount": 4343} +{"id": "28ffaf47-f630-449a-90aa-43ffbc2d1abd", "type": "debit", "created_at": "2022-10-29T00:00:00", "document": "99", "payer": "Mark Seidel", "amount": 4322} +{"id": "afb5df64-bac2-4e4b-b1e5-d7006ea77144", "type": "bank_slip", "created_at": "2022-02-11T00:00:00", "document": "9", "payer": "Connie Randall", "amount": 3028} +{"id": "bf055716-c9ab-4928-a1f1-5e945f026ec1", "type": "bank_slip", "created_at": "2022-10-07T00:00:00", "document": "9", "payer": "Connie Randall", "amount": 1573} +{"id": "48a4c3c8-5943-4211-9055-0b3e92696257", "type": "credit", "created_at": "2022-10-02T00:00:00", "document": "18", "payer": "Armida Kostrzewa", "amount": 8256} +{"id": "b2005e5a-4a04-4dca-92b4-9677c2786e8d", "type": "debit", "created_at": "2022-01-27T00:00:00", "document": "44", "payer": "Kevin Parry", "amount": 5613} +{"id": "8ac40bfa-c471-40f8-b978-3d08b9bfd959", "type": "debit", "created_at": "2022-07-24T00:00:00", "document": "66", "payer": "Kimberly Scott", "amount": 3855} +{"id": "a0317540-c57f-481f-af04-72a73bea84e3", "type": "debit", "created_at": "2022-01-27T00:00:00", "document": "23", "payer": "Donald Lee", "amount": 3845} +{"id": "3bca8a3e-424f-4cf8-80db-b077b7bc516f", "type": "debit", "created_at": "2022-04-22T00:00:00", "document": "44", "payer": "Kevin Parry", "amount": 8556} +{"id": "9fa8c316-7221-4e97-a0ad-8bd5f413ccfc", "type": "credit", "created_at": "2022-06-19T00:00:00", "document": "98", "payer": "Elma Snapp", "amount": 7791} +{"id": "fd101a02-413d-4be5-8130-a14bc8c6fa2d", "type": "bank_slip", "created_at": "2022-01-03T00:00:00", "document": "75", "payer": "Edie Callam", "amount": 1959} +{"id": "42c97b43-ff2c-43f7-9548-e2ee2a229853", "type": "bank_slip", "created_at": "2022-09-06T00:00:00", "document": "83", "payer": "Filomena Suther", "amount": 2718} +{"id": "1f84193a-bf6d-4691-8724-41221de9c1ee", "type": "bank_slip", "created_at": "2022-06-04T00:00:00", "document": "80", "payer": "Joyce Wimberly", "amount": 2152} +{"id": "80643521-f11c-4e77-99fe-64a9f998b172", "type": "debit", "created_at": "2022-09-26T00:00:00", "document": "83", "payer": "Filomena Suther", "amount": 5011} +{"id": "3cba4844-aabe-4b4b-87ce-037bd7a0a011", "type": "debit", "created_at": "2022-09-12T00:00:00", "document": "40", "payer": "Charles Malik", "amount": 3266} +{"id": "1a87edb7-d350-4e5b-9a55-07d033009e91", "type": "credit", "created_at": "2022-12-17T00:00:00", "document": "15", "payer": "James Blomdahl", "amount": 6307} +{"id": "e55579f0-9c6b-4f12-b04f-57b5295d2161", "type": "credit", "created_at": "2022-01-02T00:00:00", "document": "3", "payer": "Conrad Hardin", "amount": 1696} +{"id": "6396c58b-79fa-4eb7-9c24-3f28f4e79ef5", "type": "bank_slip", "created_at": "2022-06-06T00:00:00", "document": "5", "payer": "Paula Spencer", "amount": 695} +{"id": "68160bd3-ad65-40f8-940b-ee4c39d04d30", "type": "credit", "created_at": "2022-11-30T00:00:00", "document": "30", "payer": "Ronald Shurtleff", "amount": 5004} +{"id": "6cb336f3-f5e2-4cce-b5df-4d96a5a185c8", "type": "debit", "created_at": "2022-04-16T00:00:00", "document": "0", "payer": "Ruth Sheth", "amount": 1897} +{"id": "a14683a5-5f91-4c58-a626-e4e0635abd5d", "type": "debit", "created_at": "2022-03-27T00:00:00", "document": "9", "payer": "Connie Randall", "amount": 4050} +{"id": "77e42f86-135b-43ca-b621-056956274532", "type": "bank_slip", "created_at": "2022-11-25T00:00:00", "document": "89", "payer": "Antonio Cooley", "amount": 8387} +{"id": "eabe69a7-dfcf-44b9-a16a-80665071ae62", "type": "bank_slip", "created_at": "2022-02-02T00:00:00", "document": "21", "payer": "Richard Duckett", "amount": 733} +{"id": "1a1b6a75-f1d3-433b-9277-2420a99b5848", "type": "credit", "created_at": "2022-06-26T00:00:00", "document": "5", "payer": "Paula Spencer", "amount": 1677} +{"id": "1edebad6-fccc-4b12-9459-ac688c60e28c", "type": "debit", "created_at": "2022-05-07T00:00:00", "document": "62", "payer": "Latasha Rubio", "amount": 9173} +{"id": "eb74bb7e-fae5-428e-a483-cf256165d18e", "type": "debit", "created_at": "2022-07-28T00:00:00", "document": "34", "payer": "Sheila Ellard", "amount": 1237} +{"id": "04af768f-a273-43c3-a01f-f22ec275cc6f", "type": "credit", "created_at": "2022-09-13T00:00:00", "document": "68", "payer": "Pauline Marcum", "amount": 5907} +{"id": "f954196f-baba-4a7d-a659-40d83d8e6ceb", "type": "debit", "created_at": "2022-06-01T00:00:00", "document": "18", "payer": "Armida Kostrzewa", "amount": 1237} +{"id": "4d65b321-6ad9-495e-8b68-e6e6150fc990", "type": "debit", "created_at": "2022-04-11T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 4929} +{"id": "d9193514-bede-44da-92fe-c1fbb4c01cbc", "type": "bank_slip", "created_at": "2022-01-18T00:00:00", "document": "97", "payer": "Marc Greer", "amount": 989} +{"id": "96da474b-627a-4a12-a1c9-a125e50db09c", "type": "debit", "created_at": "2022-09-29T00:00:00", "document": "55", "payer": "Ashley Beauchesne", "amount": 5185} +{"id": "6fae629d-a9a8-4137-b7a9-cf87d0f057c0", "type": "debit", "created_at": "2022-04-13T00:00:00", "document": "91", "payer": "Gertrude Leishman", "amount": 4298} +{"id": "dc99be12-1ee8-4e28-8c0a-05aec86e402f", "type": "credit", "created_at": "2022-06-13T00:00:00", "document": "52", "payer": "Derek Corcoran", "amount": 1180} +{"id": "e0d9234b-16cb-465f-8693-ee11801719f8", "type": "bank_slip", "created_at": "2022-06-10T00:00:00", "document": "4", "payer": "Marcia Griffin", "amount": 2592} +{"id": "a6333b5a-490b-4946-b8d3-c615f99886af", "type": "credit", "created_at": "2022-01-28T00:00:00", "document": "65", "payer": "William Boxer", "amount": 3432} +{"id": "c540a826-7ef7-4d83-a581-d911dd88ad7a", "type": "debit", "created_at": "2022-10-30T00:00:00", "document": "11", "payer": "Jenny Jensen", "amount": 1156} +{"id": "c8f45fea-10b7-4440-afaf-42ef6a757cd1", "type": "debit", "created_at": "2022-03-12T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 2844} +{"id": "5e22cc43-1e69-42dd-9871-a0ccfc6a1264", "type": "credit", "created_at": "2022-10-11T00:00:00", "document": "77", "payer": "Michael Fultz", "amount": 6638} +{"id": "f8867c83-b743-4909-9cfd-ca6414dc98aa", "type": "debit", "created_at": "2022-07-17T00:00:00", "document": "97", "payer": "Marc Greer", "amount": 7644} +{"id": "bf1f117f-ef0f-4a40-808e-889742afdee8", "type": "bank_slip", "created_at": "2022-03-29T00:00:00", "document": "55", "payer": "Ashley Beauchesne", "amount": 3355} +{"id": "facccf83-451f-441a-ad5f-7e6ed9deff19", "type": "bank_slip", "created_at": "2022-12-28T00:00:00", "document": "59", "payer": "Elizabeth Robinson", "amount": 1247} +{"id": "8b2bdc58-322d-4674-93a7-c3e69ea15493", "type": "credit", "created_at": "2022-02-21T00:00:00", "document": "56", "payer": "Katherine Alexander", "amount": 9930} +{"id": "b8440248-5c87-427e-9a39-33f9702a1765", "type": "credit", "created_at": "2022-02-05T00:00:00", "document": "46", "payer": "Shaunda Gallegos", "amount": 2014} +{"id": "b716ca18-5536-4931-88ab-bde265527cf9", "type": "bank_slip", "created_at": "2022-05-28T00:00:00", "document": "60", "payer": "Rachel York", "amount": 7575} +{"id": "d964b24a-f627-4818-985b-bbbcb9e98e11", "type": "debit", "created_at": "2022-03-10T00:00:00", "document": "57", "payer": "David Landry", "amount": 8591} +{"id": "a01a5fb6-ae21-427f-9c8f-297542857ece", "type": "bank_slip", "created_at": "2022-05-21T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 9774} +{"id": "68fd1b19-d461-4980-aba6-450949879472", "type": "credit", "created_at": "2022-06-21T00:00:00", "document": "34", "payer": "Sheila Ellard", "amount": 7187} +{"id": "b97e9678-f813-4639-b86d-0c98dd8cb293", "type": "credit", "created_at": "2022-02-04T00:00:00", "document": "1", "payer": "Carl Teems", "amount": 9117} +{"id": "743a0a20-511c-40fa-9ea7-3ff460d47d03", "type": "bank_slip", "created_at": "2022-01-14T00:00:00", "document": "1", "payer": "Carl Teems", "amount": 4144} +{"id": "8678b5f4-0819-4641-998e-391f309c80c8", "type": "bank_slip", "created_at": "2022-05-11T00:00:00", "document": "21", "payer": "Richard Duckett", "amount": 5832} +{"id": "4be43919-cdab-40e1-9ecf-315d1a91129a", "type": "debit", "created_at": "2022-10-02T00:00:00", "document": "98", "payer": "Elma Snapp", "amount": 2384} +{"id": "e6adcfcd-ca19-4332-ab3f-7291cb328bf2", "type": "credit", "created_at": "2022-03-15T00:00:00", "document": "49", "payer": "Richard Isbell", "amount": 2357} +{"id": "cbeaa5ec-1434-4716-935f-1d216722765b", "type": "debit", "created_at": "2022-12-13T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 7642} +{"id": "af297dc2-86b4-4070-8fa7-7eb7c69d17fb", "type": "credit", "created_at": "2022-04-03T00:00:00", "document": "37", "payer": "Jane Olson", "amount": 7262} +{"id": "d57b168d-cf94-493c-9640-d3a915c8da2d", "type": "credit", "created_at": "2022-02-02T00:00:00", "document": "3", "payer": "Conrad Hardin", "amount": 6188} +{"id": "60070a7a-3437-434f-b90c-25588c94a142", "type": "bank_slip", "created_at": "2022-10-25T00:00:00", "document": "40", "payer": "Charles Malik", "amount": 6697} +{"id": "d2080e3e-c524-4002-96e6-c5ed0f9ec155", "type": "debit", "created_at": "2022-08-27T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 9847} +{"id": "e5d85b12-572d-4594-bc15-56d4792f7e1d", "type": "bank_slip", "created_at": "2022-08-07T00:00:00", "document": "69", "payer": "Mark Evans", "amount": 7304} +{"id": "3f22e5bb-9cc0-4b9b-b742-b854f85f12c7", "type": "credit", "created_at": "2022-05-31T00:00:00", "document": "18", "payer": "Armida Kostrzewa", "amount": 7402} +{"id": "1cb54ccd-ba8c-4ef7-b1c4-004c76f5a45c", "type": "debit", "created_at": "2022-02-28T00:00:00", "document": "5", "payer": "Paula Spencer", "amount": 4963} +{"id": "9ba95524-000e-4b32-b53f-106b75923a12", "type": "bank_slip", "created_at": "2022-08-01T00:00:00", "document": "54", "payer": "Carmela Ho", "amount": 9455} +{"id": "1c4b696b-6df1-4b92-9349-2710ec2b9940", "type": "bank_slip", "created_at": "2022-10-04T00:00:00", "document": "39", "payer": "Brendan Pease", "amount": 1724} +{"id": "fa384e35-b33f-4e4f-b309-f345a5aacac4", "type": "credit", "created_at": "2022-01-09T00:00:00", "document": "27", "payer": "Devin Felt", "amount": 912} +{"id": "346b082c-312d-4f4e-ab7f-644c9d37896d", "type": "credit", "created_at": "2022-09-27T00:00:00", "document": "54", "payer": "Carmela Ho", "amount": 7928} +{"id": "346bac46-ba70-4033-ae84-ee33e8c89e38", "type": "credit", "created_at": "2022-06-03T00:00:00", "document": "91", "payer": "Gertrude Leishman", "amount": 2741} +{"id": "9e54a36b-c7ff-4654-b685-a24647d38c01", "type": "credit", "created_at": "2022-03-24T00:00:00", "document": "73", "payer": "Fe Bartkowiak", "amount": 6390} +{"id": "c4108c2a-2295-4d1f-9836-be035cba2b90", "type": "bank_slip", "created_at": "2022-01-04T00:00:00", "document": "30", "payer": "Ronald Shurtleff", "amount": 6372} +{"id": "33d8208e-de37-4887-8ccb-673831dc1f0b", "type": "bank_slip", "created_at": "2022-07-10T00:00:00", "document": "13", "payer": "Janet Perry", "amount": 3778} +{"id": "4a0061d9-fe7f-4942-a94c-4da417b15024", "type": "debit", "created_at": "2022-12-06T00:00:00", "document": "34", "payer": "Sheila Ellard", "amount": 3375} +{"id": "5e139790-138d-4ca3-aad4-dde983a82edb", "type": "debit", "created_at": "2022-12-17T00:00:00", "document": "20", "payer": "Luis Moffett", "amount": 4539} +{"id": "f783a2c1-0ba0-45c6-87c4-fd79ce859f76", "type": "bank_slip", "created_at": "2022-06-13T00:00:00", "document": "82", "payer": "Juan Federico", "amount": 3259} +{"id": "ad8485ee-f9aa-4e9b-81ec-cc83b5f58c18", "type": "credit", "created_at": "2022-07-12T00:00:00", "document": "27", "payer": "Devin Felt", "amount": 431} +{"id": "49b75b62-eabf-4865-8ee2-b8c0d36b09e5", "type": "credit", "created_at": "2022-10-19T00:00:00", "document": "95", "payer": "Sarah Mcguire", "amount": 8273} +{"id": "4ea31a13-bce4-494c-ac26-de8d137b20c7", "type": "bank_slip", "created_at": "2022-07-01T00:00:00", "document": "90", "payer": "Michael Griffin", "amount": 9545} +{"id": "419b823b-43c2-45cd-af36-aa038c9b3610", "type": "bank_slip", "created_at": "2022-01-30T00:00:00", "document": "90", "payer": "Michael Griffin", "amount": 4191} +{"id": "6a830415-159c-44e0-b5bf-32f0af7406cc", "type": "credit", "created_at": "2022-07-18T00:00:00", "document": "70", "payer": "Patrick Davis", "amount": 6320} +{"id": "7c057252-dc77-4cb7-8acc-e223a4f9aa21", "type": "bank_slip", "created_at": "2022-05-04T00:00:00", "document": "54", "payer": "Carmela Ho", "amount": 9456} +{"id": "ebe7a963-81d7-41e5-9cac-bdf60a389723", "type": "debit", "created_at": "2022-12-22T00:00:00", "document": "39", "payer": "Brendan Pease", "amount": 7526} +{"id": "e3a7cbe4-1061-4e2e-9403-cd97134e1603", "type": "credit", "created_at": "2022-06-09T00:00:00", "document": "61", "payer": "Ladonna Cooper", "amount": 79} +{"id": "330ce4b4-ce9a-4af3-a179-0a466765bbea", "type": "bank_slip", "created_at": "2022-11-24T00:00:00", "document": "68", "payer": "Pauline Marcum", "amount": 942} +{"id": "41fa6e2f-f3e8-4a61-b852-d6ad2a1a2d36", "type": "credit", "created_at": "2022-10-21T00:00:00", "document": "28", "payer": "Mark Williams", "amount": 6473} +{"id": "a9604c8d-47d3-4567-9351-76a2b4972560", "type": "credit", "created_at": "2022-01-25T00:00:00", "document": "34", "payer": "Sheila Ellard", "amount": 696} +{"id": "384cae57-0080-460c-b774-d10da21830a5", "type": "debit", "created_at": "2022-10-29T00:00:00", "document": "14", "payer": "Eleanore Hocutt", "amount": 9489} +{"id": "a9ec68f7-f7b3-447f-a13c-d76a61ddaec5", "type": "credit", "created_at": "2022-06-10T00:00:00", "document": "74", "payer": "Norma Brumit", "amount": 7701} +{"id": "8b976f9c-53bf-4d02-851a-8fc42df65c52", "type": "credit", "created_at": "2022-11-03T00:00:00", "document": "16", "payer": "Gary Kozak", "amount": 6907} +{"id": "58e29752-8088-4466-8b15-b182149a02c2", "type": "credit", "created_at": "2022-07-26T00:00:00", "document": "25", "payer": "Calvin Reid", "amount": 4753} +{"id": "12c79929-8623-4568-854f-36b185a7d6b1", "type": "credit", "created_at": "2022-03-06T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 5657} +{"id": "0178b124-8619-4fea-bff5-16e07537ec39", "type": "bank_slip", "created_at": "2022-12-30T00:00:00", "document": "39", "payer": "Brendan Pease", "amount": 3183} +{"id": "1803434e-4ff5-42b3-bae6-f17127fd87f9", "type": "debit", "created_at": "2022-04-14T00:00:00", "document": "70", "payer": "Patrick Davis", "amount": 7139} +{"id": "a71a2b75-ba54-4329-aff8-487ca0db5a07", "type": "credit", "created_at": "2022-12-06T00:00:00", "document": "85", "payer": "Susan Wolcott", "amount": 5853} +{"id": "ed8f441f-a880-4ed3-bde6-2a69ff336af5", "type": "debit", "created_at": "2022-04-08T00:00:00", "document": "27", "payer": "Devin Felt", "amount": 9484} +{"id": "00df54c3-881d-4170-8550-d29a995b22b7", "type": "bank_slip", "created_at": "2022-10-08T00:00:00", "document": "75", "payer": "Edie Callam", "amount": 9854} +{"id": "38740701-365e-4e93-9dbf-d144d31e709e", "type": "bank_slip", "created_at": "2022-04-23T00:00:00", "document": "5", "payer": "Paula Spencer", "amount": 7680} +{"id": "60e26b84-f5eb-4bb4-98e8-7c655a0065cb", "type": "debit", "created_at": "2022-07-03T00:00:00", "document": "25", "payer": "Calvin Reid", "amount": 4252} +{"id": "95ccc77b-4c91-4713-b924-02fd82f22c30", "type": "credit", "created_at": "2022-01-31T00:00:00", "document": "58", "payer": "Erin Rhoads", "amount": 9801} +{"id": "59d8e05f-ff37-47fb-8d4b-3d9665528c45", "type": "credit", "created_at": "2022-12-08T00:00:00", "document": "79", "payer": "Steven Rapp", "amount": 607} +{"id": "a8e7cb28-41ac-4b62-ba67-b0108609593e", "type": "debit", "created_at": "2022-05-31T00:00:00", "document": "33", "payer": "Charlotte Marczak", "amount": 8951} +{"id": "090b7835-39d1-4cfe-b60d-9f435ea00f3e", "type": "debit", "created_at": "2022-03-21T00:00:00", "document": "6", "payer": "John Dickerson", "amount": 8798} +{"id": "b1f3ae84-88b7-4f2f-b1cb-8289fc5c79c6", "type": "debit", "created_at": "2022-07-15T00:00:00", "document": "31", "payer": "Ridebito Little", "amount": 8684} +{"id": "e4428cf9-e3c8-4a2a-9fee-836093c2588b", "type": "bank_slip", "created_at": "2022-07-06T00:00:00", "document": "33", "payer": "Charlotte Marczak", "amount": 3165} +{"id": "74b8dec0-3299-41d3-8262-25ea7e79550b", "type": "bank_slip", "created_at": "2022-01-24T00:00:00", "document": "51", "payer": "Kenneth Stewart", "amount": 2740} +{"id": "a607ab90-908d-4557-b9fb-8972008525b5", "type": "bank_slip", "created_at": "2022-07-22T00:00:00", "document": "8", "payer": "Nicky Jones", "amount": 7279} +{"id": "0508d6e6-a6cf-45e5-8e00-eee2487397e4", "type": "credit", "created_at": "2022-06-02T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 5046} +{"id": "1dc09c32-e7e4-4ad8-ae2a-b8bb05fb50a4", "type": "bank_slip", "created_at": "2022-06-11T00:00:00", "document": "32", "payer": "Barbara Harris", "amount": 9915} +{"id": "b158f765-5057-44cc-a4b2-94fbd7156451", "type": "bank_slip", "created_at": "2022-11-13T00:00:00", "document": "12", "payer": "Susan Woodward", "amount": 6326} +{"id": "e1e1688d-1b45-427e-bd8b-4f5778b1ed76", "type": "bank_slip", "created_at": "2022-04-16T00:00:00", "document": "5", "payer": "Paula Spencer", "amount": 6200} +{"id": "6000a90f-878c-451b-a762-acf5c7c77289", "type": "bank_slip", "created_at": "2022-03-24T00:00:00", "document": "16", "payer": "Gary Kozak", "amount": 6886} +{"id": "cae6cf8f-f871-4440-8405-8577c7f8d791", "type": "bank_slip", "created_at": "2022-11-08T00:00:00", "document": "46", "payer": "Shaunda Gallegos", "amount": 8513} +{"id": "945013f7-b0bd-4951-9f23-955f59cab2bc", "type": "credit", "created_at": "2022-12-07T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 3331} +{"id": "5ddcf2e4-c527-40b3-8899-2e3903fd79c4", "type": "credit", "created_at": "2022-03-02T00:00:00", "document": "73", "payer": "Fe Bartkowiak", "amount": 9504} +{"id": "1972e75c-7207-4e2b-9e11-51eaceed0a38", "type": "debit", "created_at": "2022-09-06T00:00:00", "document": "55", "payer": "Ashley Beauchesne", "amount": 5005} +{"id": "b3f87b17-9df1-437a-aaef-9265b98b2538", "type": "bank_slip", "created_at": "2022-11-19T00:00:00", "document": "84", "payer": "Rick Reid", "amount": 6371} +{"id": "70b6acf2-c86f-4ffb-9420-4fcb1ab4f5cf", "type": "bank_slip", "created_at": "2022-07-29T00:00:00", "document": "59", "payer": "Elizabeth Robinson", "amount": 8994} +{"id": "61fceb6b-dde9-4c66-b780-fbb42021bf2a", "type": "bank_slip", "created_at": "2022-09-11T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 8052} +{"id": "4e742551-ed93-402e-b7e2-0b6926e39c02", "type": "debit", "created_at": "2022-05-10T00:00:00", "document": "85", "payer": "Susan Wolcott", "amount": 5976} +{"id": "174d38df-c0e0-4528-838f-62de8751f58f", "type": "debit", "created_at": "2022-08-05T00:00:00", "document": "83", "payer": "Filomena Suther", "amount": 825} +{"id": "281fb9fd-d293-4158-933e-e22a6ace2ad6", "type": "credit", "created_at": "2022-03-17T00:00:00", "document": "15", "payer": "James Blomdahl", "amount": 4068} +{"id": "874d6d43-878c-4b00-95bc-cbc4134247b8", "type": "debit", "created_at": "2022-08-05T00:00:00", "document": "9", "payer": "Connie Randall", "amount": 299} +{"id": "bcf59d0a-2051-4efb-a654-0fc57b720790", "type": "bank_slip", "created_at": "2022-12-12T00:00:00", "document": "98", "payer": "Elma Snapp", "amount": 4436} +{"id": "96f4df1f-6f38-4a05-8f14-daf89eef4732", "type": "credit", "created_at": "2022-09-12T00:00:00", "document": "91", "payer": "Gertrude Leishman", "amount": 8003} +{"id": "cd30d475-751b-4ea3-8e8e-63703bc4b0f8", "type": "credit", "created_at": "2022-06-15T00:00:00", "document": "91", "payer": "Gertrude Leishman", "amount": 795} +{"id": "f82aec62-2bb1-49fa-baee-73085d95f2be", "type": "debit", "created_at": "2022-11-22T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 6967} +{"id": "b8eabddf-c2e3-4128-94b9-0627a9984c64", "type": "bank_slip", "created_at": "2022-04-25T00:00:00", "document": "0", "payer": "Ruth Sheth", "amount": 1557} +{"id": "3d6f5b89-d3f5-4a31-acb7-412ac2f6ec2d", "type": "credit", "created_at": "2022-12-09T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 7450} +{"id": "de1a3f77-e4da-47aa-a1b2-d06f0b70b269", "type": "credit", "created_at": "2022-06-20T00:00:00", "document": "48", "payer": "Lori Carter", "amount": 6650} +{"id": "92de1ed7-834d-4326-909f-cc04858a7d2a", "type": "debit", "created_at": "2022-09-07T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 6839} +{"id": "2b1700c0-4aee-4c1b-9adb-efd66c4c66be", "type": "debit", "created_at": "2022-06-02T00:00:00", "document": "26", "payer": "Robert Krupp", "amount": 6201} +{"id": "81e9896d-fbb2-4ccd-8ba3-82e93ddc9ba8", "type": "debit", "created_at": "2022-02-24T00:00:00", "document": "1", "payer": "Carl Teems", "amount": 413} +{"id": "d69e01df-db4c-41a1-bd16-30b85b9afaac", "type": "bank_slip", "created_at": "2022-03-18T00:00:00", "document": "45", "payer": "Shanita Bergesen", "amount": 8230} +{"id": "66526dd9-14ff-4f6f-93e9-25bff28c4673", "type": "bank_slip", "created_at": "2022-08-26T00:00:00", "document": "21", "payer": "Richard Duckett", "amount": 5614} +{"id": "dd28ff56-db1b-40f4-9634-3b6249d4ead9", "type": "bank_slip", "created_at": "2022-04-16T00:00:00", "document": "84", "payer": "Rick Reid", "amount": 7148} +{"id": "671a164b-72f5-4ad7-9d8d-c4231b1614a1", "type": "credit", "created_at": "2022-10-02T00:00:00", "document": "3", "payer": "Conrad Hardin", "amount": 5898} +{"id": "56c50f35-5ce6-4e35-b086-10eb0e2c547a", "type": "bank_slip", "created_at": "2022-09-14T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 9324} +{"id": "d539ff03-875c-46e3-943e-23f4d597f95e", "type": "credit", "created_at": "2022-06-01T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 2084} +{"id": "a108ee67-56ca-4cfd-9545-10f4f0ba1ad2", "type": "debit", "created_at": "2022-05-20T00:00:00", "document": "86", "payer": "Robert Kraft", "amount": 1924} +{"id": "f94e04eb-f351-4de3-bc2b-a6f511b98673", "type": "bank_slip", "created_at": "2022-06-04T00:00:00", "document": "25", "payer": "Calvin Reid", "amount": 3248} +{"id": "e0554b28-8894-499d-843d-2588f815e22f", "type": "credit", "created_at": "2022-08-01T00:00:00", "document": "2", "payer": "Ella Tatum", "amount": 3240} +{"id": "b3583016-cd7f-4d56-b89e-edbd7d6c9a67", "type": "credit", "created_at": "2022-03-18T00:00:00", "document": "3", "payer": "Conrad Hardin", "amount": 868} +{"id": "81191197-fda9-45c2-8f1b-89d997e9c541", "type": "debit", "created_at": "2022-02-13T00:00:00", "document": "8", "payer": "Nicky Jones", "amount": 9277} +{"id": "7e688a8a-4d7e-4e0a-9d85-28d748d460bf", "type": "credit", "created_at": "2022-11-24T00:00:00", "document": "14", "payer": "Eleanore Hocutt", "amount": 1458} +{"id": "3c8c6c74-756c-407e-95bd-3f327b4fc2e5", "type": "bank_slip", "created_at": "2022-11-07T00:00:00", "document": "1", "payer": "Carl Teems", "amount": 8079} +{"id": "7185488a-bd1e-4ca0-a9b3-ff54a7b696c1", "type": "debit", "created_at": "2022-06-21T00:00:00", "document": "65", "payer": "William Boxer", "amount": 7013} +{"id": "cae3f157-cfc8-43fd-98f1-a001d24e18f6", "type": "bank_slip", "created_at": "2022-12-04T00:00:00", "document": "38", "payer": "Sandra Gould", "amount": 9496} +{"id": "91e8146e-64a3-4a77-a665-edade9b83b8e", "type": "debit", "created_at": "2022-10-29T00:00:00", "document": "98", "payer": "Elma Snapp", "amount": 4049} +{"id": "bb1c1927-9023-42b1-851f-ee87db91fd69", "type": "credit", "created_at": "2022-03-03T00:00:00", "document": "57", "payer": "David Landry", "amount": 6480} +{"id": "35a4bd7d-c6af-4edd-8adc-b1415b964c5b", "type": "debit", "created_at": "2022-05-18T00:00:00", "document": "34", "payer": "Sheila Ellard", "amount": 8914} +{"id": "11f5e727-aa77-49c4-bcb4-7fd914e11d53", "type": "bank_slip", "created_at": "2022-07-16T00:00:00", "document": "47", "payer": "Dustin Diller", "amount": 7814} +{"id": "3d2dc784-eefb-47f7-9eb0-9324909d1d31", "type": "credit", "created_at": "2022-06-12T00:00:00", "document": "93", "payer": "George Lesane", "amount": 6331} +{"id": "93846602-5234-4ed7-8275-762aa07aa507", "type": "debit", "created_at": "2022-09-01T00:00:00", "document": "13", "payer": "Janet Perry", "amount": 8074} +{"id": "b32234bd-25f3-4d97-9c06-19c96126e4f8", "type": "bank_slip", "created_at": "2022-02-26T00:00:00", "document": "87", "payer": "Emily Cockerill", "amount": 2045} +{"id": "1b2d7b36-ae8b-4c07-a08b-7b82975dcb7e", "type": "debit", "created_at": "2022-10-28T00:00:00", "document": "86", "payer": "Robert Kraft", "amount": 6388} +{"id": "9a25008e-92bf-43df-8b60-bf452c96f27c", "type": "bank_slip", "created_at": "2022-12-24T00:00:00", "document": "3", "payer": "Conrad Hardin", "amount": 2249} +{"id": "589e81fe-1df0-4ed6-8d3a-a0bb4d21d966", "type": "bank_slip", "created_at": "2022-07-06T00:00:00", "document": "68", "payer": "Pauline Marcum", "amount": 8600} +{"id": "0d154442-0e4b-4853-8af3-d04500d683b0", "type": "debit", "created_at": "2022-02-27T00:00:00", "document": "90", "payer": "Michael Griffin", "amount": 7866} +{"id": "056cae01-c6e4-420a-9b9f-1b11976ca1ec", "type": "debit", "created_at": "2022-03-08T00:00:00", "document": "44", "payer": "Kevin Parry", "amount": 4245} +{"id": "686f011b-46bd-44ff-911f-2bf89ee9a9df", "type": "credit", "created_at": "2022-02-19T00:00:00", "document": "58", "payer": "Erin Rhoads", "amount": 5758} +{"id": "50796dfb-e0ea-4b0d-aaf1-6b9447d509c0", "type": "debit", "created_at": "2022-10-26T00:00:00", "document": "32", "payer": "Barbara Harris", "amount": 270} +{"id": "0f839f6b-51ef-49ee-a51d-7403fc20227c", "type": "debit", "created_at": "2022-07-13T00:00:00", "document": "82", "payer": "Juan Federico", "amount": 6472} +{"id": "0d58a904-b1e3-4d4b-85c3-0bb5cace2328", "type": "debit", "created_at": "2022-06-30T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 3911} +{"id": "5f10c1d3-44fd-4849-8351-9abd2f394931", "type": "credit", "created_at": "2022-05-01T00:00:00", "document": "91", "payer": "Gertrude Leishman", "amount": 7249} +{"id": "95eff0ee-dfef-43ef-a2df-4ca1a33c7d52", "type": "bank_slip", "created_at": "2022-12-11T00:00:00", "document": "69", "payer": "Mark Evans", "amount": 6023} +{"id": "e86cbebd-2db2-41c9-8941-3a046f77bf78", "type": "bank_slip", "created_at": "2022-05-21T00:00:00", "document": "6", "payer": "John Dickerson", "amount": 2102} +{"id": "27cbb55c-98cc-493d-bd7f-754e237f9a5d", "type": "debit", "created_at": "2022-12-01T00:00:00", "document": "75", "payer": "Edie Callam", "amount": 3854} +{"id": "2198ec7b-7043-47ae-8603-2d24f6354dbe", "type": "credit", "created_at": "2022-04-17T00:00:00", "document": "92", "payer": "Amber Hudson", "amount": 2789} +{"id": "d456b85a-b5ec-42b9-886c-ae87ae90b07d", "type": "credit", "created_at": "2022-12-07T00:00:00", "document": "1", "payer": "Carl Teems", "amount": 4779} +{"id": "bd6e862b-8a87-431f-945f-d465da0aa333", "type": "debit", "created_at": "2022-09-06T00:00:00", "document": "12", "payer": "Susan Woodward", "amount": 8759} +{"id": "4f769ff2-f90d-43a2-b5dd-3c457a6e7e22", "type": "credit", "created_at": "2022-01-17T00:00:00", "document": "33", "payer": "Charlotte Marczak", "amount": 1691} +{"id": "8d93986e-8e41-462b-8b79-c5b064709ec4", "type": "credit", "created_at": "2022-09-16T00:00:00", "document": "62", "payer": "Latasha Rubio", "amount": 5124} +{"id": "dff818e6-3e79-44b5-ac04-faa8a3b250b9", "type": "bank_slip", "created_at": "2022-03-20T00:00:00", "document": "20", "payer": "Luis Moffett", "amount": 3167} +{"id": "b8657edb-d19b-4bb7-bc12-97ef17dfdf34", "type": "bank_slip", "created_at": "2022-12-23T00:00:00", "document": "56", "payer": "Katherine Alexander", "amount": 6242} +{"id": "507b7db8-e752-4393-bdcc-6872e4f0c55e", "type": "credit", "created_at": "2022-04-08T00:00:00", "document": "24", "payer": "Susan Bostic", "amount": 1785} +{"id": "531060fb-0877-41cc-b5b3-c54ee2ec335b", "type": "debit", "created_at": "2022-08-10T00:00:00", "document": "37", "payer": "Jane Olson", "amount": 7241} +{"id": "d7d3bb6c-fc1c-47ab-a263-1d7cdf2b3f90", "type": "credit", "created_at": "2022-11-19T00:00:00", "document": "23", "payer": "Donald Lee", "amount": 1791} +{"id": "3c0218c1-ccb6-484a-bf4b-33f808006b6a", "type": "bank_slip", "created_at": "2022-08-01T00:00:00", "document": "2", "payer": "Ella Tatum", "amount": 6656} +{"id": "9e5c8c2a-f85f-4561-b1d2-417cf2ac626b", "type": "credit", "created_at": "2022-10-14T00:00:00", "document": "45", "payer": "Shanita Bergesen", "amount": 7351} +{"id": "a33a80ec-dda8-4dbd-ae48-acd59866e19a", "type": "bank_slip", "created_at": "2022-08-04T00:00:00", "document": "67", "payer": "Wiley Goetz", "amount": 4291} +{"id": "fdd91e0f-8d3f-42e6-a05f-4711e1a4321f", "type": "debit", "created_at": "2022-03-13T00:00:00", "document": "85", "payer": "Susan Wolcott", "amount": 8615} +{"id": "fcc99d46-0c90-44a2-9fb3-91b5fdadb409", "type": "bank_slip", "created_at": "2022-05-20T00:00:00", "document": "80", "payer": "Joyce Wimberly", "amount": 6819} +{"id": "44fe7e70-fe39-4387-aedd-a893e571a619", "type": "debit", "created_at": "2022-11-09T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 499} +{"id": "2033c783-0852-476d-9b09-100ec8e8e0e9", "type": "credit", "created_at": "2022-12-03T00:00:00", "document": "33", "payer": "Charlotte Marczak", "amount": 5115} +{"id": "abb0b84c-df6c-41ce-b3bd-cd8b3c8004c2", "type": "debit", "created_at": "2022-09-16T00:00:00", "document": "3", "payer": "Conrad Hardin", "amount": 7134} +{"id": "371fb97f-ef8c-407f-95fa-1125111b06e2", "type": "bank_slip", "created_at": "2022-10-21T00:00:00", "document": "16", "payer": "Gary Kozak", "amount": 1229} +{"id": "7147e5d6-1fb3-427c-8553-2a1d67d048eb", "type": "bank_slip", "created_at": "2022-06-24T00:00:00", "document": "87", "payer": "Emily Cockerill", "amount": 4844} +{"id": "3a8d43c1-9c50-462f-8041-878a85c02fa4", "type": "debit", "created_at": "2022-03-10T00:00:00", "document": "45", "payer": "Shanita Bergesen", "amount": 2794} +{"id": "0d4a985e-dd04-40aa-a7b0-3d308a3a4a5b", "type": "bank_slip", "created_at": "2022-06-09T00:00:00", "document": "35", "payer": "Maggie Auten", "amount": 272} +{"id": "d21ef233-3927-420d-8aed-cbbdaa0e0a71", "type": "bank_slip", "created_at": "2022-08-26T00:00:00", "document": "9", "payer": "Connie Randall", "amount": 3472} +{"id": "100e2d0e-5129-42f4-baf0-5ed88a8aa3f4", "type": "credit", "created_at": "2022-01-08T00:00:00", "document": "41", "payer": "Tamera Boone", "amount": 7910} +{"id": "f73df99a-68ef-46a5-af2d-261657b318bb", "type": "credit", "created_at": "2022-11-09T00:00:00", "document": "19", "payer": "Patrick Monson", "amount": 7403} +{"id": "91f8f8c5-c46c-457d-9e9f-d251373fbc50", "type": "debit", "created_at": "2022-08-07T00:00:00", "document": "88", "payer": "Gabrielle Santoyo", "amount": 7117} +{"id": "de193bef-ba29-437a-9cc2-3d4941e4d5f3", "type": "debit", "created_at": "2022-10-04T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 216} +{"id": "d28196ea-02bf-42f9-826b-ff12edaffe06", "type": "bank_slip", "created_at": "2022-04-23T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 793} +{"id": "80a0e640-5f9d-4f30-9511-11d5d7d52719", "type": "debit", "created_at": "2022-05-11T00:00:00", "document": "78", "payer": "Paul debiten", "amount": 5580} +{"id": "d462c7a1-e780-4cb2-898d-f78e80775a54", "type": "bank_slip", "created_at": "2022-10-15T00:00:00", "document": "93", "payer": "George Lesane", "amount": 3000} +{"id": "35002dd9-6fb7-4913-894e-b5b5c8c4d352", "type": "debit", "created_at": "2022-09-10T00:00:00", "document": "82", "payer": "Juan Federico", "amount": 7845} +{"id": "32390563-2173-449e-93f1-0657ba810ade", "type": "bank_slip", "created_at": "2022-08-16T00:00:00", "document": "61", "payer": "Ladonna Cooper", "amount": 8579} +{"id": "ba08e186-9dc7-4890-a38e-e8fba0fb0950", "type": "credit", "created_at": "2022-04-08T00:00:00", "document": "71", "payer": "Florence Henderson", "amount": 1813} +{"id": "dfedd01d-20ac-4ca3-a155-ed43ecb947d2", "type": "debit", "created_at": "2022-11-23T00:00:00", "document": "58", "payer": "Erin Rhoads", "amount": 4845} +{"id": "bb9bc39f-6767-49c0-b6cc-49d88f70d300", "type": "credit", "created_at": "2022-10-15T00:00:00", "document": "96", "payer": "Earl Morgan", "amount": 8688} +{"id": "ade8abef-4292-4d78-9fc5-29518edbf3c0", "type": "credit", "created_at": "2022-08-05T00:00:00", "document": "65", "payer": "William Boxer", "amount": 8648} +{"id": "deb79c7b-b39d-4511-8852-03c3a2447cd5", "type": "debit", "created_at": "2022-05-23T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 5829} +{"id": "40e6de86-8803-49b5-8d70-53c476e869fb", "type": "credit", "created_at": "2022-11-07T00:00:00", "document": "67", "payer": "Wiley Goetz", "amount": 9145} +{"id": "43553ccc-18cc-4f38-9bac-e20346c8a3b6", "type": "debit", "created_at": "2022-11-19T00:00:00", "document": "96", "payer": "Earl Morgan", "amount": 5335} +{"id": "6ecc9550-2a54-4cc7-9c2d-5054cd51dbf4", "type": "credit", "created_at": "2022-04-28T00:00:00", "document": "45", "payer": "Shanita Bergesen", "amount": 6657} +{"id": "a84fe461-732a-42de-83a8-498bc727176a", "type": "debit", "created_at": "2022-02-11T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 9496} +{"id": "6226c696-b995-4777-acfd-0f9cb55cc7a0", "type": "bank_slip", "created_at": "2022-12-01T00:00:00", "document": "12", "payer": "Susan Woodward", "amount": 5418} +{"id": "3c0e6bfc-7bc5-41a4-8ea6-5b09cd3ae919", "type": "debit", "created_at": "2022-07-28T00:00:00", "document": "21", "payer": "Richard Duckett", "amount": 4186} +{"id": "0aa46247-d07f-455b-8fa0-1e37009a5d17", "type": "credit", "created_at": "2022-07-02T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 2507} +{"id": "0005dde7-47cf-40df-a29a-8913f1ddede8", "type": "bank_slip", "created_at": "2022-10-11T00:00:00", "document": "24", "payer": "Susan Bostic", "amount": 1870} +{"id": "dcdf3b67-de56-4678-8258-b51ab9503175", "type": "credit", "created_at": "2022-04-24T00:00:00", "document": "61", "payer": "Ladonna Cooper", "amount": 2110} +{"id": "d1df5c89-9c94-42fd-bead-ef35b160fa25", "type": "debit", "created_at": "2022-05-23T00:00:00", "document": "70", "payer": "Patrick Davis", "amount": 7509} +{"id": "991f2326-06af-406d-a4c9-76ed6ca369b8", "type": "credit", "created_at": "2022-07-10T00:00:00", "document": "63", "payer": "Pearl Lemaire", "amount": 8614} +{"id": "30d2f2e7-4d6b-4176-86cd-3973adb72b4a", "type": "debit", "created_at": "2022-02-28T00:00:00", "document": "75", "payer": "Edie Callam", "amount": 1436} +{"id": "df7bcbf4-a957-4eca-b09b-0501c9692378", "type": "credit", "created_at": "2022-07-06T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 7888} +{"id": "b3119075-f541-494d-a341-349f070c134e", "type": "bank_slip", "created_at": "2022-08-12T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 6377} +{"id": "a8f8640f-3569-48d9-bfd6-35caa52b564f", "type": "debit", "created_at": "2022-12-09T00:00:00", "document": "58", "payer": "Erin Rhoads", "amount": 2914} +{"id": "288de595-555a-4462-a2d4-6ae185e7ea4a", "type": "bank_slip", "created_at": "2022-01-26T00:00:00", "document": "14", "payer": "Eleanore Hocutt", "amount": 4945} +{"id": "5d325535-d498-4d19-af4e-e2f4739c6919", "type": "bank_slip", "created_at": "2022-09-10T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 1048} +{"id": "a960b3a2-3637-4a15-8a84-ae8002f641f6", "type": "bank_slip", "created_at": "2022-03-08T00:00:00", "document": "52", "payer": "Derek Corcoran", "amount": 79} +{"id": "267b99ae-a947-47b7-b5c4-ad3c9124c906", "type": "bank_slip", "created_at": "2022-03-25T00:00:00", "document": "58", "payer": "Erin Rhoads", "amount": 2089} +{"id": "865f87de-f2ed-448b-a42b-97f742f3db53", "type": "debit", "created_at": "2022-09-21T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 8090} +{"id": "0b4da3a7-2ca3-4783-b1a6-acfe5954973f", "type": "bank_slip", "created_at": "2022-11-10T00:00:00", "document": "82", "payer": "Juan Federico", "amount": 2647} +{"id": "a42b4caf-790a-4392-bf17-71cf499ba1b8", "type": "debit", "created_at": "2022-08-31T00:00:00", "document": "66", "payer": "Kimberly Scott", "amount": 8100} +{"id": "f9092e68-be8c-4474-9378-005ea75e56e5", "type": "bank_slip", "created_at": "2022-05-20T00:00:00", "document": "13", "payer": "Janet Perry", "amount": 3673} +{"id": "228c42d8-bf3a-414c-b3d5-e910b2c59eaf", "type": "bank_slip", "created_at": "2022-07-07T00:00:00", "document": "10", "payer": "Emanuel Robinson", "amount": 8590} +{"id": "2573250e-0171-43f9-acab-5c3a32bdfca7", "type": "debit", "created_at": "2022-05-07T00:00:00", "document": "79", "payer": "Steven Rapp", "amount": 6781} +{"id": "346dd59d-eb8f-4791-99a8-42df5bbe1af5", "type": "bank_slip", "created_at": "2022-03-09T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 316} +{"id": "4e87c320-cfa5-4d7b-8771-6b2fb9ca4035", "type": "debit", "created_at": "2022-02-17T00:00:00", "document": "6", "payer": "John Dickerson", "amount": 1245} +{"id": "2a205cec-7c4c-42ee-bf15-7d7c24013485", "type": "bank_slip", "created_at": "2022-03-06T00:00:00", "document": "65", "payer": "William Boxer", "amount": 9582} +{"id": "ce659948-b47f-46f7-b00a-1bd8e9ca29cd", "type": "debit", "created_at": "2022-10-06T00:00:00", "document": "88", "payer": "Gabrielle Santoyo", "amount": 3537} +{"id": "c9c18fb7-e912-441f-8b35-a8d301c47f47", "type": "credit", "created_at": "2022-01-26T00:00:00", "document": "16", "payer": "Gary Kozak", "amount": 9514} +{"id": "84836abf-abbb-49b6-9989-8aa1699dc215", "type": "debit", "created_at": "2022-05-29T00:00:00", "document": "56", "payer": "Katherine Alexander", "amount": 2790} +{"id": "0037af9a-24ce-4d11-9d72-fe409e919200", "type": "credit", "created_at": "2022-06-28T00:00:00", "document": "27", "payer": "Devin Felt", "amount": 2014} +{"id": "3f560a93-9d04-45d6-b078-865700658c34", "type": "credit", "created_at": "2022-10-09T00:00:00", "document": "11", "payer": "Jenny Jensen", "amount": 1294} +{"id": "75377a17-6dbf-4732-9acc-1e3f49bb5c83", "type": "debit", "created_at": "2022-09-06T00:00:00", "document": "99", "payer": "Mark Seidel", "amount": 2709} +{"id": "11ff84ab-0d78-4e54-809a-cfa40598128d", "type": "credit", "created_at": "2022-06-08T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 2075} +{"id": "35e068ae-7561-4ed2-883a-cd81d342ae69", "type": "credit", "created_at": "2022-01-05T00:00:00", "document": "30", "payer": "Ronald Shurtleff", "amount": 8302} +{"id": "622e9e7e-b231-4b77-9cb6-4a553cb69851", "type": "credit", "created_at": "2022-04-29T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 5416} +{"id": "5d0544bb-f9d9-42b7-bcd6-cc08bb4802da", "type": "bank_slip", "created_at": "2022-08-23T00:00:00", "document": "42", "payer": "Carolyn Ponyah", "amount": 5993} +{"id": "3e3332e5-4bcc-4cee-95b9-d0d836b15c0f", "type": "credit", "created_at": "2022-01-28T00:00:00", "document": "30", "payer": "Ronald Shurtleff", "amount": 6558} +{"id": "7ef8ebf3-228d-41ed-a8ec-4f34730bb000", "type": "debit", "created_at": "2022-03-04T00:00:00", "document": "97", "payer": "Marc Greer", "amount": 5723} +{"id": "927a5ae9-4c82-48a7-8299-49066eee02a8", "type": "credit", "created_at": "2022-01-01T00:00:00", "document": "57", "payer": "David Landry", "amount": 9733} +{"id": "59f3c7e7-f47b-4eca-a529-5106073bab05", "type": "credit", "created_at": "2022-09-21T00:00:00", "document": "99", "payer": "Mark Seidel", "amount": 5590} +{"id": "c08612ce-1697-431c-9886-216616fad1e6", "type": "credit", "created_at": "2022-07-31T00:00:00", "document": "52", "payer": "Derek Corcoran", "amount": 9909} +{"id": "99efb935-f353-4327-803a-5eee67c23aa5", "type": "bank_slip", "created_at": "2022-12-19T00:00:00", "document": "95", "payer": "Sarah Mcguire", "amount": 8989} +{"id": "33ea5746-7a85-4397-a961-9e5466067fdf", "type": "credit", "created_at": "2022-05-19T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 2597} +{"id": "b44d6dc6-01ee-44f7-83b7-038e623c4c4c", "type": "credit", "created_at": "2022-01-03T00:00:00", "document": "69", "payer": "Mark Evans", "amount": 6680} +{"id": "b8a8d195-79f2-4aeb-81bf-7fc6cba541b2", "type": "bank_slip", "created_at": "2022-12-29T00:00:00", "document": "46", "payer": "Shaunda Gallegos", "amount": 3360} +{"id": "4a00cb4f-7dbb-4b7d-9670-1dfad67c649b", "type": "debit", "created_at": "2022-05-26T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 9304} +{"id": "648cebc9-5c00-40d2-91dd-1b714b0e8800", "type": "debit", "created_at": "2022-02-13T00:00:00", "document": "51", "payer": "Kenneth Stewart", "amount": 7593} +{"id": "0b451864-adc8-4219-a4ae-5de3b432e025", "type": "debit", "created_at": "2022-01-01T00:00:00", "document": "97", "payer": "Marc Greer", "amount": 3458} +{"id": "503f00fa-f849-407c-a91e-36658cb46182", "type": "debit", "created_at": "2022-03-20T00:00:00", "document": "86", "payer": "Robert Kraft", "amount": 9985} +{"id": "7cbf166c-11c3-42da-86bc-59341486e2f7", "type": "bank_slip", "created_at": "2022-01-25T00:00:00", "document": "9", "payer": "Connie Randall", "amount": 1005} +{"id": "b5b80114-c8f5-48f1-b7fc-5c204ba9cdb8", "type": "debit", "created_at": "2022-05-31T00:00:00", "document": "19", "payer": "Patrick Monson", "amount": 7578} +{"id": "e207a460-7969-43e5-81aa-3e0a3a2677d9", "type": "debit", "created_at": "2022-11-11T00:00:00", "document": "7", "payer": "Maria Bonney", "amount": 7876} +{"id": "c526c7b4-f72a-4395-b47b-ef4596804a75", "type": "debit", "created_at": "2022-05-13T00:00:00", "document": "32", "payer": "Barbara Harris", "amount": 1495} +{"id": "eb7a22a9-eb3f-47a4-be76-b2786b020181", "type": "credit", "created_at": "2022-12-14T00:00:00", "document": "4", "payer": "Marcia Griffin", "amount": 6318} +{"id": "73c89ff5-5dbb-4aaf-96c4-dd9353cdccf6", "type": "bank_slip", "created_at": "2022-08-09T00:00:00", "document": "34", "payer": "Sheila Ellard", "amount": 4258} +{"id": "4837c455-ccfe-40c9-9151-89a64b39dde9", "type": "credit", "created_at": "2022-09-04T00:00:00", "document": "74", "payer": "Norma Brumit", "amount": 9160} +{"id": "da5f256d-0cf2-4e80-9c12-e3c029a12aeb", "type": "bank_slip", "created_at": "2022-10-25T00:00:00", "document": "19", "payer": "Patrick Monson", "amount": 6511} +{"id": "737ea891-a05b-49e6-8911-3a7f62f5317d", "type": "bank_slip", "created_at": "2022-01-26T00:00:00", "document": "47", "payer": "Dustin Diller", "amount": 509} +{"id": "db0f5de4-1a29-4d62-8c85-fa7c7e577da3", "type": "credit", "created_at": "2022-10-09T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 2057} +{"id": "5f36550a-c1f8-4998-a24f-ab38588e6c79", "type": "bank_slip", "created_at": "2022-06-23T00:00:00", "document": "68", "payer": "Pauline Marcum", "amount": 3069} +{"id": "9ab7914c-37a1-4013-8148-569b3eb5b135", "type": "debit", "created_at": "2022-05-18T00:00:00", "document": "75", "payer": "Edie Callam", "amount": 2220} +{"id": "10186da8-e723-4739-a5a5-4de409038c3f", "type": "credit", "created_at": "2022-11-26T00:00:00", "document": "60", "payer": "Rachel York", "amount": 8861} +{"id": "7a6cacb5-fede-47b6-aa5d-6b8f35dd5dd7", "type": "debit", "created_at": "2022-06-03T00:00:00", "document": "45", "payer": "Shanita Bergesen", "amount": 7028} +{"id": "c285401b-dbbd-4e36-a093-61d1f0c1fab4", "type": "bank_slip", "created_at": "2022-01-08T00:00:00", "document": "93", "payer": "George Lesane", "amount": 4485} +{"id": "533b2039-82b3-4c00-adcc-22af9342d201", "type": "debit", "created_at": "2022-08-28T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 7084} +{"id": "dc62e67b-6242-45ef-a19d-e94fb1bf4382", "type": "credit", "created_at": "2022-02-02T00:00:00", "document": "83", "payer": "Filomena Suther", "amount": 4334} +{"id": "c3d6aaa8-95c9-4d85-bccb-71d16bd608ea", "type": "debit", "created_at": "2022-02-01T00:00:00", "document": "79", "payer": "Steven Rapp", "amount": 5340} +{"id": "2fe1fc6f-4755-4783-b60f-647353ae698a", "type": "debit", "created_at": "2022-09-07T00:00:00", "document": "60", "payer": "Rachel York", "amount": 5169} +{"id": "22d0b3f6-a5fd-49ea-bde1-49ee5df594c1", "type": "credit", "created_at": "2022-02-26T00:00:00", "document": "70", "payer": "Patrick Davis", "amount": 6836} +{"id": "fd109356-478f-47f3-9a4a-faa0d8bce7db", "type": "bank_slip", "created_at": "2022-05-10T00:00:00", "document": "33", "payer": "Charlotte Marczak", "amount": 1032} +{"id": "d3f68c72-e244-4c3e-9c59-ad6bb768b896", "type": "credit", "created_at": "2022-10-08T00:00:00", "document": "56", "payer": "Katherine Alexander", "amount": 6481} +{"id": "d9ef7da1-3e22-42e0-a5f7-42f905c6d6f9", "type": "debit", "created_at": "2022-07-26T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 1810} +{"id": "b788ae42-4561-4f29-bc85-ce754805843f", "type": "bank_slip", "created_at": "2022-03-23T00:00:00", "document": "29", "payer": "Timothy Short", "amount": 1311} +{"id": "7ad4808a-62c8-4aed-b3f6-e8dc2ba6cf4f", "type": "debit", "created_at": "2022-03-14T00:00:00", "document": "46", "payer": "Shaunda Gallegos", "amount": 7164} +{"id": "fbd50f3d-11b4-4b4d-86a3-8bf18441e8fc", "type": "bank_slip", "created_at": "2022-03-12T00:00:00", "document": "40", "payer": "Charles Malik", "amount": 1128} +{"id": "cbaaca5f-25d6-4af0-9cc4-072da3ab8a51", "type": "debit", "created_at": "2022-05-11T00:00:00", "document": "66", "payer": "Kimberly Scott", "amount": 1939} +{"id": "d3408fde-d404-4be6-9a54-97a9c31cc2a7", "type": "credit", "created_at": "2022-05-10T00:00:00", "document": "43", "payer": "Gary Jensen", "amount": 4497} +{"id": "c164899d-95ae-4851-b5e0-1c47953f0862", "type": "debit", "created_at": "2022-06-22T00:00:00", "document": "55", "payer": "Ashley Beauchesne", "amount": 849} +{"id": "a1f76f23-7168-4875-9f09-8a8cb69e7b68", "type": "debit", "created_at": "2022-08-25T00:00:00", "document": "30", "payer": "Ronald Shurtleff", "amount": 237} +{"id": "1f4a8f16-87bf-4f08-b942-444234b1bf79", "type": "debit", "created_at": "2022-05-15T00:00:00", "document": "0", "payer": "Ruth Sheth", "amount": 6226} +{"id": "789aaea9-28ec-44dd-b8ae-37cb2ad46a97", "type": "credit", "created_at": "2023-01-01T00:00:00", "document": "73", "payer": "Fe Bartkowiak", "amount": 5453} +{"id": "0163d1db-43c0-4f06-ad5e-b062ebda3c29", "type": "credit", "created_at": "2022-02-27T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 6678} +{"id": "6d9f8880-6a9d-4a87-813a-ca8fb19fd1c9", "type": "credit", "created_at": "2022-08-19T00:00:00", "document": "14", "payer": "Eleanore Hocutt", "amount": 3265} +{"id": "fc5d2197-182f-4541-8084-94e86a5a4641", "type": "credit", "created_at": "2022-10-02T00:00:00", "document": "56", "payer": "Katherine Alexander", "amount": 9599} +{"id": "f0e65c3b-b334-4e33-be89-8ac0e48804e6", "type": "debit", "created_at": "2022-12-09T00:00:00", "document": "25", "payer": "Calvin Reid", "amount": 3801} +{"id": "ab4b5d55-6cfa-41f8-bf0f-73d173a97918", "type": "bank_slip", "created_at": "2022-04-13T00:00:00", "document": "10", "payer": "Emanuel Robinson", "amount": 3963} +{"id": "310c0f54-ddc1-4b5b-848c-e22f0771c6d1", "type": "debit", "created_at": "2022-10-16T00:00:00", "document": "17", "payer": "Janice Coughlin", "amount": 5987} +{"id": "a6b8d7d9-6d1c-4761-9d3c-3c3997076f7d", "type": "bank_slip", "created_at": "2022-01-30T00:00:00", "document": "59", "payer": "Elizabeth Robinson", "amount": 8996} +{"id": "a4431727-2e71-4696-a618-1d38fcdeebd3", "type": "bank_slip", "created_at": "2022-11-21T00:00:00", "document": "97", "payer": "Marc Greer", "amount": 2534} +{"id": "ca64b80b-c562-4dfe-85c9-53e3ed70c12b", "type": "debit", "created_at": "2022-11-10T00:00:00", "document": "73", "payer": "Fe Bartkowiak", "amount": 8501} +{"id": "eb030a2d-1317-42c7-b6b8-056d562e699d", "type": "credit", "created_at": "2022-07-19T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 558} +{"id": "34f083ff-0eb3-4f41-93f6-18db7a52fa83", "type": "debit", "created_at": "2022-05-01T00:00:00", "document": "78", "payer": "Paul debiten", "amount": 3405} +{"id": "192544d3-ba5b-43b6-accf-e2e167d60942", "type": "credit", "created_at": "2022-08-23T00:00:00", "document": "61", "payer": "Ladonna Cooper", "amount": 9446} +{"id": "34cf3c42-8d2d-484f-9478-a3063783a536", "type": "credit", "created_at": "2022-12-10T00:00:00", "document": "38", "payer": "Sandra Gould", "amount": 6161} +{"id": "5a69e9a5-b6b1-4917-8a91-54aaa79b2ddd", "type": "bank_slip", "created_at": "2022-03-28T00:00:00", "document": "10", "payer": "Emanuel Robinson", "amount": 3896} +{"id": "59706a44-e8d3-4016-8c67-613d037a9daf", "type": "debit", "created_at": "2022-06-30T00:00:00", "document": "59", "payer": "Elizabeth Robinson", "amount": 428} +{"id": "4f947780-8369-453d-b6f7-11818e202cb1", "type": "debit", "created_at": "2022-03-22T00:00:00", "document": "47", "payer": "Dustin Diller", "amount": 1433} +{"id": "d955296f-d669-4b58-ae97-0852004dcf71", "type": "debit", "created_at": "2022-06-28T00:00:00", "document": "16", "payer": "Gary Kozak", "amount": 6726} +{"id": "c302f1d4-add9-452b-ad02-6f1af6f79afe", "type": "credit", "created_at": "2022-06-25T00:00:00", "document": "96", "payer": "Earl Morgan", "amount": 9607} +{"id": "22c1f659-2116-43d7-ac63-b5d123859ea0", "type": "bank_slip", "created_at": "2022-11-11T00:00:00", "document": "80", "payer": "Joyce Wimberly", "amount": 6463} +{"id": "57cb714f-e967-473e-a25f-360e1ded0571", "type": "debit", "created_at": "2022-10-21T00:00:00", "document": "82", "payer": "Juan Federico", "amount": 4374} +{"id": "58afc7b8-17bf-45d7-8f98-a2b6e5740db4", "type": "debit", "created_at": "2022-09-11T00:00:00", "document": "37", "payer": "Jane Olson", "amount": 268} +{"id": "6aa09d08-5076-490e-a461-f025ea5d29a8", "type": "debit", "created_at": "2022-08-03T00:00:00", "document": "97", "payer": "Marc Greer", "amount": 5294} +{"id": "9236bf26-07a7-4ede-ad2f-0e90578c1002", "type": "credit", "created_at": "2022-06-22T00:00:00", "document": "89", "payer": "Antonio Cooley", "amount": 7257} +{"id": "e22cf846-01a4-415c-b08b-8ee8798d9f86", "type": "bank_slip", "created_at": "2022-01-04T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 2249} +{"id": "d425ee69-7081-4b8d-8076-7ff8fe9e3ecd", "type": "debit", "created_at": "2022-08-27T00:00:00", "document": "82", "payer": "Juan Federico", "amount": 5683} +{"id": "c1c8bacd-8733-4d8a-bd8d-f8816ccc851c", "type": "credit", "created_at": "2022-06-23T00:00:00", "document": "2", "payer": "Ella Tatum", "amount": 6650} +{"id": "eb61dd3e-dfa9-42c4-b9f2-6144f28080d2", "type": "debit", "created_at": "2022-12-21T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 903} +{"id": "762bd62f-5e31-4740-a0c5-ecd412e502db", "type": "debit", "created_at": "2022-05-17T00:00:00", "document": "26", "payer": "Robert Krupp", "amount": 7000} +{"id": "5406d961-d033-434f-a968-2e6f29a78184", "type": "bank_slip", "created_at": "2022-08-15T00:00:00", "document": "67", "payer": "Wiley Goetz", "amount": 8355} +{"id": "79ce5093-8589-4886-b7ff-375dc85e2a32", "type": "debit", "created_at": "2022-08-20T00:00:00", "document": "20", "payer": "Luis Moffett", "amount": 7763} +{"id": "00e6c810-b055-4a3f-a9f2-12cbe7000eb2", "type": "bank_slip", "created_at": "2022-08-08T00:00:00", "document": "8", "payer": "Nicky Jones", "amount": 9171} +{"id": "1276c8ba-7b3a-46ca-b58e-b6a4c9b22930", "type": "credit", "created_at": "2022-06-06T00:00:00", "document": "55", "payer": "Ashley Beauchesne", "amount": 798} +{"id": "a491718b-4903-46a4-91e7-467fcd98807b", "type": "debit", "created_at": "2022-02-23T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 1224} +{"id": "50390dff-40ff-4423-ba5d-edd72e97bd13", "type": "debit", "created_at": "2022-08-23T00:00:00", "document": "99", "payer": "Mark Seidel", "amount": 4977} +{"id": "f3f80e9b-5577-49eb-9260-3820129cab23", "type": "debit", "created_at": "2022-10-28T00:00:00", "document": "69", "payer": "Mark Evans", "amount": 2164} +{"id": "dc108a63-d818-4f6f-b9bb-688dbf1ae90d", "type": "credit", "created_at": "2022-10-12T00:00:00", "document": "3", "payer": "Conrad Hardin", "amount": 2873} +{"id": "66eef8d0-e53f-417e-a256-55aca06b2b68", "type": "debit", "created_at": "2022-03-30T00:00:00", "document": "60", "payer": "Rachel York", "amount": 8929} +{"id": "3d2a3252-9803-44ed-a476-24824b3f2e62", "type": "debit", "created_at": "2022-05-24T00:00:00", "document": "84", "payer": "Rick Reid", "amount": 5696} +{"id": "946e64c7-227b-4d95-b1a9-7ed42932ec9c", "type": "bank_slip", "created_at": "2022-05-03T00:00:00", "document": "42", "payer": "Carolyn Ponyah", "amount": 7103} +{"id": "a9a1f6ed-7003-4bf4-aeff-5b4ba425f59d", "type": "debit", "created_at": "2022-11-16T00:00:00", "document": "96", "payer": "Earl Morgan", "amount": 854} +{"id": "2a8474bf-bcb9-475d-968e-470c86a1cb47", "type": "debit", "created_at": "2022-04-05T00:00:00", "document": "58", "payer": "Erin Rhoads", "amount": 4596} +{"id": "2a1d1577-0a20-4aa9-8a1b-2dca9230adbf", "type": "bank_slip", "created_at": "2022-12-17T00:00:00", "document": "86", "payer": "Robert Kraft", "amount": 538} +{"id": "656250f0-3df6-4755-a22e-bff8c494edd9", "type": "bank_slip", "created_at": "2022-12-24T00:00:00", "document": "77", "payer": "Michael Fultz", "amount": 9178} +{"id": "531901f8-9015-4a7f-a882-06dd525e563a", "type": "bank_slip", "created_at": "2022-05-13T00:00:00", "document": "54", "payer": "Carmela Ho", "amount": 9020} +{"id": "b5031d15-8aef-4c4e-908d-c20250b5219f", "type": "credit", "created_at": "2022-05-26T00:00:00", "document": "93", "payer": "George Lesane", "amount": 9809} +{"id": "0449d399-c41d-4c5d-bde9-f764b1a83447", "type": "credit", "created_at": "2022-07-24T00:00:00", "document": "1", "payer": "Carl Teems", "amount": 3559} +{"id": "bf85aaa5-59c9-4610-9fcf-e963f025c774", "type": "credit", "created_at": "2022-09-23T00:00:00", "document": "66", "payer": "Kimberly Scott", "amount": 6816} +{"id": "abca1f53-ff3c-470f-aac1-be4340a34ca2", "type": "debit", "created_at": "2022-06-05T00:00:00", "document": "6", "payer": "John Dickerson", "amount": 4290} +{"id": "12bb90ec-31f0-47b7-b48c-3898a8c23eb3", "type": "credit", "created_at": "2022-10-08T00:00:00", "document": "76", "payer": "Megan Wallace", "amount": 3790} +{"id": "44f2077d-8562-4290-b1eb-3d1ad54b5926", "type": "bank_slip", "created_at": "2022-12-16T00:00:00", "document": "60", "payer": "Rachel York", "amount": 3964} +{"id": "38d82d54-2bf2-4928-a140-19cfd1bb5c31", "type": "credit", "created_at": "2022-01-30T00:00:00", "document": "24", "payer": "Susan Bostic", "amount": 2910} +{"id": "6fd2d0f2-8f73-41f1-944e-af779479d6b3", "type": "bank_slip", "created_at": "2022-08-05T00:00:00", "document": "70", "payer": "Patrick Davis", "amount": 8928} +{"id": "5d36bb22-b6d2-46cb-a4bd-62fbfa5af599", "type": "credit", "created_at": "2022-04-05T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 6257} +{"id": "afcd3409-fc14-4117-8ef4-6fc36e5e6f22", "type": "debit", "created_at": "2022-09-25T00:00:00", "document": "9", "payer": "Connie Randall", "amount": 2461} +{"id": "2f74997e-ec59-4a65-bb5b-2bfb01d5fed4", "type": "bank_slip", "created_at": "2022-05-01T00:00:00", "document": "23", "payer": "Donald Lee", "amount": 1025} +{"id": "4c6468e7-452a-48d0-a1ac-2e9a01756c23", "type": "bank_slip", "created_at": "2022-06-13T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 7375} +{"id": "de2c714a-da40-4c34-a1c6-a938d305aef0", "type": "credit", "created_at": "2022-08-18T00:00:00", "document": "71", "payer": "Florence Henderson", "amount": 7779} +{"id": "24d34c2d-65d3-42f0-abbe-727290b56592", "type": "credit", "created_at": "2022-03-14T00:00:00", "document": "26", "payer": "Robert Krupp", "amount": 4503} +{"id": "c2702ab3-a1e7-4aeb-80d6-825a169bc1e9", "type": "debit", "created_at": "2022-06-06T00:00:00", "document": "17", "payer": "Janice Coughlin", "amount": 6249} +{"id": "2d10c65c-9953-46a8-a164-f23b5d6134df", "type": "credit", "created_at": "2023-01-01T00:00:00", "document": "67", "payer": "Wiley Goetz", "amount": 2646} +{"id": "63494b82-a4d7-42c9-aaba-e4ca7e5ccc80", "type": "debit", "created_at": "2022-10-27T00:00:00", "document": "20", "payer": "Luis Moffett", "amount": 6629} +{"id": "a6fe0e88-b5b9-4b31-8f9d-083d5c08f42c", "type": "credit", "created_at": "2022-11-20T00:00:00", "document": "54", "payer": "Carmela Ho", "amount": 9950} +{"id": "f8ab30d9-8427-4e13-a348-10dc761890bc", "type": "debit", "created_at": "2022-04-02T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 7211} +{"id": "117606af-db73-4266-b3be-f604ce2dcb0e", "type": "credit", "created_at": "2022-07-15T00:00:00", "document": "48", "payer": "Lori Carter", "amount": 3835} +{"id": "2df45f39-90f0-4ce6-8e46-3cbef2fb5263", "type": "debit", "created_at": "2022-08-08T00:00:00", "document": "75", "payer": "Edie Callam", "amount": 6504} +{"id": "40ac3296-355d-4c51-849c-5060ff087318", "type": "debit", "created_at": "2022-11-02T00:00:00", "document": "47", "payer": "Dustin Diller", "amount": 996} +{"id": "1f07e48c-0021-4e9e-bf17-36cca857de51", "type": "credit", "created_at": "2022-09-20T00:00:00", "document": "68", "payer": "Pauline Marcum", "amount": 4689} +{"id": "cc2f2e10-3423-4758-bbed-7c54e0218f94", "type": "debit", "created_at": "2022-11-11T00:00:00", "document": "63", "payer": "Pearl Lemaire", "amount": 1165} +{"id": "1777e2c7-f425-4842-b1fb-fb036f62d464", "type": "debit", "created_at": "2022-12-01T00:00:00", "document": "91", "payer": "Gertrude Leishman", "amount": 5129} +{"id": "9e759bad-5611-41c8-ba0a-0619f70f091b", "type": "debit", "created_at": "2022-06-28T00:00:00", "document": "30", "payer": "Ronald Shurtleff", "amount": 1319} +{"id": "23c7eafc-2778-42bc-a296-1084a6a0374a", "type": "credit", "created_at": "2022-03-16T00:00:00", "document": "30", "payer": "Ronald Shurtleff", "amount": 2647} +{"id": "04fb8785-a717-48fd-a8d5-4f55124c9255", "type": "bank_slip", "created_at": "2022-02-08T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 6687} +{"id": "aa5ee73f-67a2-4b45-a7e0-b885d96455dd", "type": "bank_slip", "created_at": "2022-04-11T00:00:00", "document": "54", "payer": "Carmela Ho", "amount": 7664} +{"id": "1d61824f-aff9-453a-99e0-af4f7c43541b", "type": "bank_slip", "created_at": "2022-12-28T00:00:00", "document": "17", "payer": "Janice Coughlin", "amount": 6908} +{"id": "e6c99ea2-1581-42e8-8583-b9fda9ac7f60", "type": "credit", "created_at": "2022-10-25T00:00:00", "document": "37", "payer": "Jane Olson", "amount": 1718} +{"id": "9519d04f-5d16-424d-b167-0994187416d7", "type": "debit", "created_at": "2022-09-17T00:00:00", "document": "8", "payer": "Nicky Jones", "amount": 6916} +{"id": "e268fdb5-0a3a-49ab-b26a-c9c1cf300152", "type": "credit", "created_at": "2022-07-07T00:00:00", "document": "96", "payer": "Earl Morgan", "amount": 6558} +{"id": "f321ce19-4a88-4337-8188-cb7346fedb2f", "type": "credit", "created_at": "2022-04-19T00:00:00", "document": "99", "payer": "Mark Seidel", "amount": 7652} +{"id": "7d3b90ab-7cdb-4556-8df3-b35172cc06c8", "type": "debit", "created_at": "2022-07-20T00:00:00", "document": "0", "payer": "Ruth Sheth", "amount": 7401} +{"id": "1e212636-5c17-48fd-9994-9e3ae34fecb0", "type": "credit", "created_at": "2022-08-04T00:00:00", "document": "21", "payer": "Richard Duckett", "amount": 8733} +{"id": "bb085244-0c29-441b-8784-222fc03adfd6", "type": "credit", "created_at": "2022-05-13T00:00:00", "document": "50", "payer": "Karen Lewis", "amount": 9688} +{"id": "5699fd40-7e2f-4907-9e98-d05f3b51ac55", "type": "bank_slip", "created_at": "2022-06-30T00:00:00", "document": "84", "payer": "Rick Reid", "amount": 9716} +{"id": "7eddd545-fdec-4fbd-a47f-e4a1d3bc8f73", "type": "credit", "created_at": "2022-04-15T00:00:00", "document": "25", "payer": "Calvin Reid", "amount": 9609} +{"id": "f246362e-c8d4-4b33-9020-93d81da42818", "type": "credit", "created_at": "2022-09-01T00:00:00", "document": "16", "payer": "Gary Kozak", "amount": 6355} +{"id": "aaf9a491-b8bd-44b4-b719-d0c5d822633b", "type": "credit", "created_at": "2022-07-19T00:00:00", "document": "88", "payer": "Gabrielle Santoyo", "amount": 902} +{"id": "98db7397-808f-4f1c-b672-8a8881cbdd89", "type": "debit", "created_at": "2022-02-01T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 5368} +{"id": "3d3c536b-b7fc-4811-ad3b-1ee0d77102aa", "type": "debit", "created_at": "2022-02-24T00:00:00", "document": "12", "payer": "Susan Woodward", "amount": 5060} +{"id": "0d5a58b6-5769-4ffb-8bc1-a90e0c5ca414", "type": "debit", "created_at": "2022-02-20T00:00:00", "document": "31", "payer": "Ridebito Little", "amount": 3770} +{"id": "6e506e6e-e92f-490b-87be-1ea803509a7a", "type": "credit", "created_at": "2022-03-19T00:00:00", "document": "17", "payer": "Janice Coughlin", "amount": 8861} +{"id": "41acdb82-e2c2-4409-a3f7-8d24c6ea2fdf", "type": "credit", "created_at": "2022-02-21T00:00:00", "document": "62", "payer": "Latasha Rubio", "amount": 7142} +{"id": "3718e100-f711-4e1c-8332-2b13d85910ae", "type": "debit", "created_at": "2022-07-31T00:00:00", "document": "38", "payer": "Sandra Gould", "amount": 8402} +{"id": "17ce8de1-e96c-4ae9-b60a-a253cf722e60", "type": "debit", "created_at": "2022-12-10T00:00:00", "document": "30", "payer": "Ronald Shurtleff", "amount": 4544} +{"id": "79e87a83-cff3-4c2d-8c88-21b406ac99e0", "type": "debit", "created_at": "2022-02-10T00:00:00", "document": "48", "payer": "Lori Carter", "amount": 9989} +{"id": "d165c4a5-f0cb-4a42-a2a3-58f5d221d798", "type": "debit", "created_at": "2022-06-18T00:00:00", "document": "77", "payer": "Michael Fultz", "amount": 8410} +{"id": "c3724bb0-53d0-4b3f-9b96-2aac75f2861f", "type": "debit", "created_at": "2022-03-18T00:00:00", "document": "71", "payer": "Florence Henderson", "amount": 6472} +{"id": "557aa8a4-bc67-4642-adff-95a089d2f96b", "type": "credit", "created_at": "2022-02-13T00:00:00", "document": "10", "payer": "Emanuel Robinson", "amount": 1674} +{"id": "349286e0-bae2-4141-9c65-78ea5ae3b3b2", "type": "bank_slip", "created_at": "2022-08-20T00:00:00", "document": "1", "payer": "Carl Teems", "amount": 7785} +{"id": "90f0bfcb-4aab-430d-8233-1e4199103824", "type": "credit", "created_at": "2022-10-11T00:00:00", "document": "78", "payer": "Paul debiten", "amount": 47} +{"id": "19d20a80-3be0-45b7-abae-df66e946e01b", "type": "debit", "created_at": "2022-02-16T00:00:00", "document": "17", "payer": "Janice Coughlin", "amount": 5586} +{"id": "28e3e82a-6d57-4198-b17c-eb921ebb36bd", "type": "credit", "created_at": "2022-09-08T00:00:00", "document": "67", "payer": "Wiley Goetz", "amount": 9965} +{"id": "29cbb909-15e3-4726-9cf4-f04582b076b6", "type": "bank_slip", "created_at": "2022-10-12T00:00:00", "document": "61", "payer": "Ladonna Cooper", "amount": 4119} +{"id": "522d1d42-8c25-4a4e-980b-e600ea74ec94", "type": "debit", "created_at": "2022-06-06T00:00:00", "document": "41", "payer": "Tamera Boone", "amount": 5654} +{"id": "19992f8f-4f17-4adf-8f80-c0c307a4c7c0", "type": "credit", "created_at": "2022-02-22T00:00:00", "document": "71", "payer": "Florence Henderson", "amount": 3872} +{"id": "00eb60ff-b689-47ea-90eb-2d50051bfe15", "type": "bank_slip", "created_at": "2022-11-11T00:00:00", "document": "28", "payer": "Mark Williams", "amount": 9296} +{"id": "d391c308-e9bd-4421-9a37-c14248b21d27", "type": "debit", "created_at": "2022-09-20T00:00:00", "document": "88", "payer": "Gabrielle Santoyo", "amount": 1528} +{"id": "00f15b85-e823-4d7b-a29d-b4f3111ecc27", "type": "credit", "created_at": "2022-02-27T00:00:00", "document": "49", "payer": "Richard Isbell", "amount": 3926} +{"id": "1562af89-2889-42ac-a35e-323f34e31640", "type": "credit", "created_at": "2022-05-14T00:00:00", "document": "16", "payer": "Gary Kozak", "amount": 3813} +{"id": "45826702-9787-4ac4-9b0a-566a9b6a2c8b", "type": "credit", "created_at": "2022-01-15T00:00:00", "document": "3", "payer": "Conrad Hardin", "amount": 8450} +{"id": "d45a6fd6-4c9c-4dbc-8811-45d7894e7afa", "type": "credit", "created_at": "2022-07-26T00:00:00", "document": "87", "payer": "Emily Cockerill", "amount": 7207} +{"id": "25f3d576-9bb7-49dc-9e96-cd88c0eb7c8c", "type": "credit", "created_at": "2022-05-25T00:00:00", "document": "23", "payer": "Donald Lee", "amount": 7086} +{"id": "1cf0a46d-21e7-4c45-8324-c396ce367b5c", "type": "debit", "created_at": "2022-03-18T00:00:00", "document": "4", "payer": "Marcia Griffin", "amount": 6041} +{"id": "2385f28c-f4a9-43d3-9c00-6809696028b4", "type": "credit", "created_at": "2022-03-18T00:00:00", "document": "45", "payer": "Shanita Bergesen", "amount": 9156} +{"id": "62a94903-3788-4fa3-af82-25a2e1ac7404", "type": "credit", "created_at": "2022-06-27T00:00:00", "document": "5", "payer": "Paula Spencer", "amount": 8106} +{"id": "2dd57903-c970-4bea-9386-d5f46e90ae78", "type": "bank_slip", "created_at": "2022-08-15T00:00:00", "document": "56", "payer": "Katherine Alexander", "amount": 7265} +{"id": "013ac330-a41b-4c86-a90c-0654695b3077", "type": "bank_slip", "created_at": "2022-08-04T00:00:00", "document": "93", "payer": "George Lesane", "amount": 5323} +{"id": "b51d4144-0005-4fa8-bf0c-c4c02d2fee1a", "type": "credit", "created_at": "2022-05-14T00:00:00", "document": "1", "payer": "Carl Teems", "amount": 6230} +{"id": "e5b0cd99-d788-469b-b474-ffe18cf024b3", "type": "bank_slip", "created_at": "2022-08-22T00:00:00", "document": "67", "payer": "Wiley Goetz", "amount": 965} +{"id": "abd8a33d-6f78-4d8a-aa6f-415344e863de", "type": "bank_slip", "created_at": "2022-05-24T00:00:00", "document": "77", "payer": "Michael Fultz", "amount": 4782} +{"id": "fb2ac759-3bb0-4133-9c4c-35c1a2b6cdf5", "type": "debit", "created_at": "2022-08-16T00:00:00", "document": "35", "payer": "Maggie Auten", "amount": 5046} +{"id": "d864c4f6-4417-47e9-977b-aa93e6f58a33", "type": "bank_slip", "created_at": "2022-09-11T00:00:00", "document": "95", "payer": "Sarah Mcguire", "amount": 1768} +{"id": "e7d15df8-67a9-43a3-bab1-cbb1a9ab1ea3", "type": "credit", "created_at": "2022-03-05T00:00:00", "document": "84", "payer": "Rick Reid", "amount": 1450} +{"id": "b4bd4513-a269-40c6-bd61-b217b4745147", "type": "bank_slip", "created_at": "2022-12-20T00:00:00", "document": "42", "payer": "Carolyn Ponyah", "amount": 3111} +{"id": "11595f7d-6e8f-4b9c-9890-c5fde6603015", "type": "credit", "created_at": "2022-07-10T00:00:00", "document": "85", "payer": "Susan Wolcott", "amount": 7198} +{"id": "98222e26-74e6-4f51-9df3-8ee9a70606dd", "type": "debit", "created_at": "2022-02-22T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 8113} +{"id": "aa6463b9-8aae-439f-8cdb-fbb976d94804", "type": "debit", "created_at": "2022-11-11T00:00:00", "document": "27", "payer": "Devin Felt", "amount": 7738} +{"id": "cf48e80b-7680-42af-b16e-1853cbecf8e8", "type": "bank_slip", "created_at": "2022-10-13T00:00:00", "document": "30", "payer": "Ronald Shurtleff", "amount": 6488} +{"id": "64e199d3-57e6-4bbb-81e2-92374b967c05", "type": "debit", "created_at": "2022-11-12T00:00:00", "document": "88", "payer": "Gabrielle Santoyo", "amount": 6869} +{"id": "e99f4ad1-cc55-4e3f-b17b-f0b945c1c239", "type": "debit", "created_at": "2022-06-29T00:00:00", "document": "39", "payer": "Brendan Pease", "amount": 9402} +{"id": "fd3238b0-6034-4e5a-885a-6801533e2123", "type": "debit", "created_at": "2022-04-27T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 6024} +{"id": "d7e3a9e9-4b32-4c90-b751-33219a036030", "type": "debit", "created_at": "2022-03-10T00:00:00", "document": "89", "payer": "Antonio Cooley", "amount": 3974} +{"id": "f5fd4419-5381-4ebf-abfa-81ec7065246e", "type": "bank_slip", "created_at": "2022-09-28T00:00:00", "document": "54", "payer": "Carmela Ho", "amount": 7297} +{"id": "c4947e8e-8bdb-44eb-b4f8-6f34e41330e4", "type": "debit", "created_at": "2022-12-31T00:00:00", "document": "48", "payer": "Lori Carter", "amount": 8936} +{"id": "3b062e32-5618-4f0a-a46d-12e4d5dabcc4", "type": "debit", "created_at": "2022-12-31T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 3639} +{"id": "fcc7a6d6-766c-4fd4-9f54-a4a5352141bb", "type": "bank_slip", "created_at": "2022-01-03T00:00:00", "document": "42", "payer": "Carolyn Ponyah", "amount": 7830} +{"id": "1590a0d0-62ff-49b1-8d0a-e7b75fbc2c89", "type": "bank_slip", "created_at": "2022-01-05T00:00:00", "document": "19", "payer": "Patrick Monson", "amount": 2606} +{"id": "ed5e55eb-42b2-4c50-9b6a-82025d4d9e35", "type": "debit", "created_at": "2022-09-08T00:00:00", "document": "95", "payer": "Sarah Mcguire", "amount": 8587} +{"id": "cc2f69d1-1d63-43b2-920b-9afb491045b1", "type": "credit", "created_at": "2022-04-16T00:00:00", "document": "55", "payer": "Ashley Beauchesne", "amount": 5193} +{"id": "840a3b1b-0868-4c12-940c-0387b61cc02b", "type": "credit", "created_at": "2022-02-03T00:00:00", "document": "13", "payer": "Janet Perry", "amount": 5952} +{"id": "3909d050-1960-4022-a7c8-b715a9cefe7a", "type": "debit", "created_at": "2022-06-20T00:00:00", "document": "60", "payer": "Rachel York", "amount": 9118} +{"id": "5fa538ee-d98c-49c2-9acb-dd42b7677d50", "type": "credit", "created_at": "2022-12-20T00:00:00", "document": "99", "payer": "Mark Seidel", "amount": 1162} +{"id": "23753b57-f76c-44ca-8a45-445e99377ad9", "type": "debit", "created_at": "2022-10-26T00:00:00", "document": "46", "payer": "Shaunda Gallegos", "amount": 2740} +{"id": "2ee8852c-2030-4631-9d01-a87fe70f4139", "type": "debit", "created_at": "2022-01-11T00:00:00", "document": "51", "payer": "Kenneth Stewart", "amount": 2489} +{"id": "c5a6bea0-7614-469a-bbdb-aef8eb78b657", "type": "credit", "created_at": "2022-04-28T00:00:00", "document": "93", "payer": "George Lesane", "amount": 7877} +{"id": "f47883f0-3464-47de-bebe-c2f4354ca3b0", "type": "credit", "created_at": "2022-02-27T00:00:00", "document": "82", "payer": "Juan Federico", "amount": 8196} +{"id": "e25d96fa-ab8b-49c5-84cf-aac78c20985e", "type": "bank_slip", "created_at": "2022-08-29T00:00:00", "document": "15", "payer": "James Blomdahl", "amount": 7450} +{"id": "31345723-2f59-4631-9517-6e1221557f28", "type": "bank_slip", "created_at": "2022-11-12T00:00:00", "document": "47", "payer": "Dustin Diller", "amount": 4636} +{"id": "44d873e5-310f-4418-ab42-81ea7ca839e8", "type": "credit", "created_at": "2022-01-09T00:00:00", "document": "16", "payer": "Gary Kozak", "amount": 5998} +{"id": "dce99128-ead3-4053-aea3-ebe25fb41317", "type": "debit", "created_at": "2022-10-14T00:00:00", "document": "89", "payer": "Antonio Cooley", "amount": 622} +{"id": "430fa3d7-781e-4898-8a8c-749adeb7aacc", "type": "credit", "created_at": "2022-11-24T00:00:00", "document": "1", "payer": "Carl Teems", "amount": 1025} +{"id": "40033358-b3cb-4c7c-906b-007ea363de4a", "type": "bank_slip", "created_at": "2022-04-05T00:00:00", "document": "10", "payer": "Emanuel Robinson", "amount": 8828} +{"id": "55b1ed04-6869-42f5-920b-a78bc146111f", "type": "bank_slip", "created_at": "2022-01-07T00:00:00", "document": "13", "payer": "Janet Perry", "amount": 859} +{"id": "16ece1db-6183-4f5e-a658-885171fff708", "type": "bank_slip", "created_at": "2022-11-04T00:00:00", "document": "50", "payer": "Karen Lewis", "amount": 2540} +{"id": "5475a970-cf88-42da-adf5-d3375eb42ce1", "type": "credit", "created_at": "2022-12-31T00:00:00", "document": "28", "payer": "Mark Williams", "amount": 3826} +{"id": "b27401f5-7d8d-45d9-b463-013b54d64c6b", "type": "bank_slip", "created_at": "2022-09-04T00:00:00", "document": "40", "payer": "Charles Malik", "amount": 1180} +{"id": "241b425f-af21-412b-8cc1-11022e2626fc", "type": "bank_slip", "created_at": "2022-12-14T00:00:00", "document": "92", "payer": "Amber Hudson", "amount": 416} +{"id": "7f0e0089-889f-4550-bd10-700b31d6015f", "type": "bank_slip", "created_at": "2022-01-14T00:00:00", "document": "76", "payer": "Megan Wallace", "amount": 6309} +{"id": "a0452c91-fcc8-48ee-8599-cb06d3958417", "type": "debit", "created_at": "2022-11-09T00:00:00", "document": "31", "payer": "Ridebito Little", "amount": 4700} +{"id": "becf9308-6e64-4967-9e9f-67d1d6ac2d2b", "type": "bank_slip", "created_at": "2022-06-20T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 5194} +{"id": "26527782-5245-45d1-93a1-6ed47acd3bbd", "type": "bank_slip", "created_at": "2022-03-25T00:00:00", "document": "42", "payer": "Carolyn Ponyah", "amount": 4629} +{"id": "4c213e1e-4f76-4c4d-a243-102d779fb895", "type": "bank_slip", "created_at": "2022-04-03T00:00:00", "document": "9", "payer": "Connie Randall", "amount": 3538} +{"id": "0a497b85-6442-4898-acbc-6d33edf9440d", "type": "debit", "created_at": "2022-12-29T00:00:00", "document": "60", "payer": "Rachel York", "amount": 620} +{"id": "96ae15a4-da30-4244-93da-8372caee9abf", "type": "credit", "created_at": "2022-01-17T00:00:00", "document": "89", "payer": "Antonio Cooley", "amount": 400} +{"id": "fedfadd1-533f-43e4-96b5-8ccb493699f8", "type": "credit", "created_at": "2022-10-08T00:00:00", "document": "24", "payer": "Susan Bostic", "amount": 5925} +{"id": "1d29fa59-b09a-4004-affa-9372ef58fbb6", "type": "bank_slip", "created_at": "2022-03-06T00:00:00", "document": "97", "payer": "Marc Greer", "amount": 6904} +{"id": "723a6c3f-d4ef-4372-9546-df67eb6b839a", "type": "credit", "created_at": "2022-02-02T00:00:00", "document": "97", "payer": "Marc Greer", "amount": 58} +{"id": "9eb8d5f1-560e-45df-93d0-0ff70b2fc306", "type": "credit", "created_at": "2022-07-30T00:00:00", "document": "76", "payer": "Megan Wallace", "amount": 1713} +{"id": "55d84a66-73fe-4f70-8c05-924dbf8e97c3", "type": "credit", "created_at": "2022-11-15T00:00:00", "document": "3", "payer": "Conrad Hardin", "amount": 205} +{"id": "4abe59ef-9945-4324-8dec-98c4d086d083", "type": "credit", "created_at": "2022-12-23T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 4083} +{"id": "0142396d-b304-4959-a954-ab00a21ac21c", "type": "debit", "created_at": "2022-10-02T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 289} +{"id": "0a61dbaa-af99-463a-b1de-eb31ad0c00dc", "type": "bank_slip", "created_at": "2022-04-27T00:00:00", "document": "80", "payer": "Joyce Wimberly", "amount": 6023} +{"id": "6263f26e-2f0d-4d07-aa5e-05db60176e7f", "type": "credit", "created_at": "2022-06-09T00:00:00", "document": "40", "payer": "Charles Malik", "amount": 377} +{"id": "2ed5b3e9-b1ab-4efb-a48b-3dc7795171e0", "type": "bank_slip", "created_at": "2022-04-16T00:00:00", "document": "42", "payer": "Carolyn Ponyah", "amount": 6562} +{"id": "c5eac5f5-f374-458b-b5c4-376d15c8fc66", "type": "debit", "created_at": "2022-01-23T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 413} +{"id": "383e9303-2cd3-424a-b7f5-b43cdf72c30a", "type": "credit", "created_at": "2022-05-22T00:00:00", "document": "96", "payer": "Earl Morgan", "amount": 8838} +{"id": "41894359-97c3-4852-b7bc-b55823bc9b06", "type": "debit", "created_at": "2022-11-20T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 4327} +{"id": "6407d992-3548-4818-9bb1-ba3196d61e7f", "type": "credit", "created_at": "2022-12-04T00:00:00", "document": "45", "payer": "Shanita Bergesen", "amount": 8916} +{"id": "72890e0d-4558-4b56-b8db-793b9c8bb3eb", "type": "credit", "created_at": "2022-02-11T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 2475} +{"id": "8197afca-940a-4cd5-a6f3-9ab380108f65", "type": "debit", "created_at": "2022-01-30T00:00:00", "document": "46", "payer": "Shaunda Gallegos", "amount": 5851} +{"id": "54db7fef-93c2-4b2a-b3d3-954999c3b5d8", "type": "bank_slip", "created_at": "2022-06-26T00:00:00", "document": "58", "payer": "Erin Rhoads", "amount": 3249} +{"id": "e69ad003-1071-4b76-b400-c078173d0a70", "type": "bank_slip", "created_at": "2022-02-11T00:00:00", "document": "13", "payer": "Janet Perry", "amount": 5876} +{"id": "59f025ef-967b-453f-b949-97bc7e15b7df", "type": "credit", "created_at": "2022-08-04T00:00:00", "document": "87", "payer": "Emily Cockerill", "amount": 7786} +{"id": "a2c31c95-6454-4ff0-a350-0803bd11ff3e", "type": "credit", "created_at": "2022-05-11T00:00:00", "document": "41", "payer": "Tamera Boone", "amount": 7494} +{"id": "04e65d31-c96c-46fe-b307-5a39306f97fd", "type": "credit", "created_at": "2022-04-07T00:00:00", "document": "91", "payer": "Gertrude Leishman", "amount": 6376} +{"id": "e6d592fd-d201-4a16-9e74-1ff1e80a0c58", "type": "bank_slip", "created_at": "2022-03-10T00:00:00", "document": "82", "payer": "Juan Federico", "amount": 5609} +{"id": "230c88a9-c2f1-4c58-905a-4f1ee8a6c953", "type": "credit", "created_at": "2022-11-17T00:00:00", "document": "89", "payer": "Antonio Cooley", "amount": 8453} +{"id": "e6a20a5d-b24c-42a8-a946-39dd51340c18", "type": "credit", "created_at": "2022-02-08T00:00:00", "document": "19", "payer": "Patrick Monson", "amount": 6165} +{"id": "3bf419f8-2baa-4afb-82bd-745cee7e0391", "type": "bank_slip", "created_at": "2022-01-06T00:00:00", "document": "93", "payer": "George Lesane", "amount": 2272} +{"id": "6c3340a9-06f7-4277-ad1b-961184606b58", "type": "credit", "created_at": "2022-08-07T00:00:00", "document": "57", "payer": "David Landry", "amount": 8608} +{"id": "015410ff-7ca4-4e99-a74a-919f4585b7fd", "type": "debit", "created_at": "2022-07-28T00:00:00", "document": "77", "payer": "Michael Fultz", "amount": 3082} +{"id": "27b1eece-c8d0-4ec3-896f-35d00d7903c0", "type": "bank_slip", "created_at": "2022-06-18T00:00:00", "document": "24", "payer": "Susan Bostic", "amount": 1759} +{"id": "3238a234-7c4c-40df-a5cb-51ac32bad998", "type": "debit", "created_at": "2022-03-26T00:00:00", "document": "55", "payer": "Ashley Beauchesne", "amount": 6779} +{"id": "9fb649b6-4978-401b-ba1a-b2e2ef130b68", "type": "credit", "created_at": "2022-06-29T00:00:00", "document": "93", "payer": "George Lesane", "amount": 8483} +{"id": "08234bee-44b8-458f-884c-3a96ed6feef6", "type": "bank_slip", "created_at": "2022-02-06T00:00:00", "document": "49", "payer": "Richard Isbell", "amount": 2944} +{"id": "7d232a84-a803-4c94-9d91-baa7f0097d4d", "type": "debit", "created_at": "2022-06-25T00:00:00", "document": "83", "payer": "Filomena Suther", "amount": 4168} +{"id": "8845d914-9bee-47e4-8b0b-1749c783158f", "type": "debit", "created_at": "2022-09-22T00:00:00", "document": "69", "payer": "Mark Evans", "amount": 1917} +{"id": "c186c318-e997-49d0-9a97-d81049108526", "type": "credit", "created_at": "2022-06-10T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 3265} +{"id": "7a8bcb45-add3-4575-9a27-c6185f02c6f5", "type": "credit", "created_at": "2022-03-31T00:00:00", "document": "84", "payer": "Rick Reid", "amount": 4285} +{"id": "daa55b23-4d45-4b10-8c78-846aee814a0f", "type": "credit", "created_at": "2022-05-06T00:00:00", "document": "19", "payer": "Patrick Monson", "amount": 5109} +{"id": "a39cdd9d-98b4-476a-8167-a3c9c877bea8", "type": "bank_slip", "created_at": "2022-11-29T00:00:00", "document": "57", "payer": "David Landry", "amount": 7169} +{"id": "0e8d6ae6-3d8c-4682-b669-dbad419602d0", "type": "credit", "created_at": "2022-01-04T00:00:00", "document": "86", "payer": "Robert Kraft", "amount": 4621} +{"id": "d0825eff-2ee6-4977-ba97-6a2defc295cc", "type": "credit", "created_at": "2022-08-01T00:00:00", "document": "19", "payer": "Patrick Monson", "amount": 1190} +{"id": "ab53ceda-4c5c-4f36-aed0-4fb871e1aaad", "type": "bank_slip", "created_at": "2022-01-18T00:00:00", "document": "85", "payer": "Susan Wolcott", "amount": 2489} +{"id": "dd81ef29-3b77-4ec4-9247-98f56cf9399b", "type": "bank_slip", "created_at": "2022-11-01T00:00:00", "document": "74", "payer": "Norma Brumit", "amount": 8933} +{"id": "5d177633-40fc-4c64-855b-61ed137abe0e", "type": "debit", "created_at": "2022-06-11T00:00:00", "document": "52", "payer": "Derek Corcoran", "amount": 5567} +{"id": "6bd71339-70ad-4811-8af2-68de79a8e0b9", "type": "debit", "created_at": "2022-02-05T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 1932} +{"id": "1a370c2c-7e16-439b-b18c-06feee34bbc2", "type": "credit", "created_at": "2022-04-28T00:00:00", "document": "59", "payer": "Elizabeth Robinson", "amount": 3264} +{"id": "f7eb2dce-e3b7-43bf-8189-845b30c11e69", "type": "credit", "created_at": "2022-06-14T00:00:00", "document": "97", "payer": "Marc Greer", "amount": 9098} +{"id": "d61fc3e1-3094-4a82-afda-54d9d6f535ca", "type": "credit", "created_at": "2022-02-12T00:00:00", "document": "90", "payer": "Michael Griffin", "amount": 5581} +{"id": "86bec851-2e9a-46d7-94d8-62bc4e1cb8fc", "type": "bank_slip", "created_at": "2022-02-12T00:00:00", "document": "57", "payer": "David Landry", "amount": 7346} +{"id": "9a577181-a1d2-417d-a79d-406dee830489", "type": "debit", "created_at": "2022-09-05T00:00:00", "document": "76", "payer": "Megan Wallace", "amount": 1666} +{"id": "ce29a78a-3ddd-448b-b939-1e2e65d495d3", "type": "bank_slip", "created_at": "2022-11-02T00:00:00", "document": "80", "payer": "Joyce Wimberly", "amount": 4397} +{"id": "f6c05b53-de54-446f-9c33-00cce430527c", "type": "credit", "created_at": "2022-08-23T00:00:00", "document": "92", "payer": "Amber Hudson", "amount": 2094} +{"id": "0c61ec29-3740-47ed-b2a1-1a0d34ab15bc", "type": "debit", "created_at": "2022-08-09T00:00:00", "document": "70", "payer": "Patrick Davis", "amount": 7673} +{"id": "d72a6477-5005-4903-b8e9-af0b762e69c0", "type": "debit", "created_at": "2022-12-10T00:00:00", "document": "8", "payer": "Nicky Jones", "amount": 2407} +{"id": "9976b0a5-7a98-41a8-9d6c-ae301a390869", "type": "credit", "created_at": "2022-06-16T00:00:00", "document": "74", "payer": "Norma Brumit", "amount": 5941} +{"id": "4ba11011-072f-44d0-9fbc-3e8ed396d41a", "type": "credit", "created_at": "2022-04-12T00:00:00", "document": "92", "payer": "Amber Hudson", "amount": 7996} +{"id": "60329630-362e-4144-b459-b188320dfa87", "type": "debit", "created_at": "2022-08-30T00:00:00", "document": "66", "payer": "Kimberly Scott", "amount": 3020} +{"id": "d5c4ad11-67aa-475e-8d31-54fa39ad6258", "type": "credit", "created_at": "2022-04-27T00:00:00", "document": "92", "payer": "Amber Hudson", "amount": 9354} +{"id": "5eaccb32-38e2-4bef-bcc5-57874a375d23", "type": "credit", "created_at": "2022-01-13T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 1371} +{"id": "0a44ce10-9819-4a35-9ac1-7c805cea0935", "type": "bank_slip", "created_at": "2022-12-28T00:00:00", "document": "58", "payer": "Erin Rhoads", "amount": 2158} +{"id": "e3e8361a-f06c-4205-b00b-35edc673fc04", "type": "debit", "created_at": "2022-04-24T00:00:00", "document": "78", "payer": "Paul debiten", "amount": 4700} +{"id": "196344b2-74f2-4325-a973-fa59589e5b41", "type": "credit", "created_at": "2022-10-25T00:00:00", "document": "66", "payer": "Kimberly Scott", "amount": 2408} +{"id": "5da6c823-5e27-4847-96ee-890e328c205d", "type": "bank_slip", "created_at": "2022-01-23T00:00:00", "document": "90", "payer": "Michael Griffin", "amount": 3210} +{"id": "b0afc981-a193-46f6-9e7f-57bfaf02d36f", "type": "debit", "created_at": "2022-08-24T00:00:00", "document": "67", "payer": "Wiley Goetz", "amount": 9658} +{"id": "d7c60606-7985-40bc-8a1f-27848c4e6807", "type": "debit", "created_at": "2022-09-29T00:00:00", "document": "96", "payer": "Earl Morgan", "amount": 1539} +{"id": "8de830ca-ef90-4b8e-8728-a053363c3fad", "type": "credit", "created_at": "2022-03-06T00:00:00", "document": "75", "payer": "Edie Callam", "amount": 1297} +{"id": "5efaa8d7-4a7e-4081-8e56-688edea27a6a", "type": "debit", "created_at": "2022-08-07T00:00:00", "document": "41", "payer": "Tamera Boone", "amount": 4961} +{"id": "b5e18bef-de44-4a8a-8da4-3af37067a19c", "type": "bank_slip", "created_at": "2022-09-04T00:00:00", "document": "58", "payer": "Erin Rhoads", "amount": 5698} +{"id": "c7c08d13-afc5-4f7c-8928-81110f3396a9", "type": "bank_slip", "created_at": "2022-03-13T00:00:00", "document": "79", "payer": "Steven Rapp", "amount": 9847} +{"id": "055b5913-e448-4a90-b57e-54c772681a1b", "type": "debit", "created_at": "2022-06-15T00:00:00", "document": "16", "payer": "Gary Kozak", "amount": 6557} +{"id": "60c548fa-e53d-49aa-b5c1-d22766f3d006", "type": "credit", "created_at": "2022-03-22T00:00:00", "document": "20", "payer": "Luis Moffett", "amount": 8664} +{"id": "2990eac1-d260-4f34-8aca-045e10353204", "type": "bank_slip", "created_at": "2022-07-17T00:00:00", "document": "70", "payer": "Patrick Davis", "amount": 8760} +{"id": "4e6a4b32-4406-47ee-9ff2-6f16ebd430a7", "type": "debit", "created_at": "2022-09-24T00:00:00", "document": "34", "payer": "Sheila Ellard", "amount": 5327} +{"id": "6426ac86-b1d9-4018-99d3-8b59877e1d20", "type": "credit", "created_at": "2022-11-16T00:00:00", "document": "89", "payer": "Antonio Cooley", "amount": 8984} +{"id": "3da26a80-1556-4285-bde1-33ef1d6ba2ae", "type": "credit", "created_at": "2022-08-27T00:00:00", "document": "65", "payer": "William Boxer", "amount": 9024} +{"id": "bac315b6-7839-4091-ade3-08d3dd3bf5ec", "type": "debit", "created_at": "2022-03-05T00:00:00", "document": "96", "payer": "Earl Morgan", "amount": 5703} +{"id": "7f81806a-22ed-4933-b0e8-8242484e8e20", "type": "debit", "created_at": "2022-10-13T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 2656} +{"id": "cda75900-6044-43dd-9013-b8c4ba6f92ba", "type": "credit", "created_at": "2022-12-23T00:00:00", "document": "35", "payer": "Maggie Auten", "amount": 2072} +{"id": "9efae137-0e99-4f9c-bd0f-be7d389863ff", "type": "bank_slip", "created_at": "2022-07-31T00:00:00", "document": "51", "payer": "Kenneth Stewart", "amount": 3805} +{"id": "47c4a36d-4df9-44ad-b887-d2d1fef8ee27", "type": "debit", "created_at": "2022-10-04T00:00:00", "document": "8", "payer": "Nicky Jones", "amount": 3008} +{"id": "419521c3-2878-4b1b-87e7-f3a65d5c8732", "type": "credit", "created_at": "2022-08-08T00:00:00", "document": "23", "payer": "Donald Lee", "amount": 8332} +{"id": "14ad48bf-fb02-4a21-9077-244e8c99577e", "type": "debit", "created_at": "2022-08-23T00:00:00", "document": "12", "payer": "Susan Woodward", "amount": 2788} +{"id": "c8a897bf-06a5-4a87-a58a-c4ea3b83ffa0", "type": "debit", "created_at": "2022-06-12T00:00:00", "document": "92", "payer": "Amber Hudson", "amount": 3671} +{"id": "886ced62-b0c9-43db-9955-c41579967460", "type": "credit", "created_at": "2022-06-15T00:00:00", "document": "85", "payer": "Susan Wolcott", "amount": 6307} +{"id": "c86efe36-9c24-4120-8d28-e3e98e4f438f", "type": "bank_slip", "created_at": "2022-10-07T00:00:00", "document": "31", "payer": "Ridebito Little", "amount": 9583} +{"id": "2e4ef53c-085a-47b8-b0af-006f19a00994", "type": "bank_slip", "created_at": "2022-03-16T00:00:00", "document": "51", "payer": "Kenneth Stewart", "amount": 5883} +{"id": "91bfd964-ca18-4676-a00d-47712da89d5b", "type": "credit", "created_at": "2022-11-18T00:00:00", "document": "23", "payer": "Donald Lee", "amount": 79} +{"id": "1f5663d4-80b6-48bb-b007-83f83f251bd6", "type": "bank_slip", "created_at": "2022-08-16T00:00:00", "document": "73", "payer": "Fe Bartkowiak", "amount": 3426} +{"id": "49a688a7-12e7-440f-b752-fb72b02fd096", "type": "bank_slip", "created_at": "2022-03-29T00:00:00", "document": "26", "payer": "Robert Krupp", "amount": 8594} +{"id": "6fdf7ff0-da08-4f23-bd64-010e39e0124e", "type": "bank_slip", "created_at": "2022-01-13T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 9107} +{"id": "f79c934b-7305-4459-a9c5-59b078822d18", "type": "debit", "created_at": "2022-03-13T00:00:00", "document": "21", "payer": "Richard Duckett", "amount": 4351} +{"id": "4851f348-a92f-4ba4-96e8-f7e1faf93ebd", "type": "credit", "created_at": "2022-10-14T00:00:00", "document": "77", "payer": "Michael Fultz", "amount": 8623} +{"id": "63130105-de1e-43f9-8e97-fc9ac8799674", "type": "credit", "created_at": "2022-12-09T00:00:00", "document": "59", "payer": "Elizabeth Robinson", "amount": 7967} +{"id": "03e42ac6-819d-4aaf-a4ee-10726f37afcc", "type": "credit", "created_at": "2022-10-23T00:00:00", "document": "32", "payer": "Barbara Harris", "amount": 809} +{"id": "ac832803-5b7a-4410-bede-fcad470872dd", "type": "bank_slip", "created_at": "2022-11-09T00:00:00", "document": "63", "payer": "Pearl Lemaire", "amount": 6925} +{"id": "cfa87631-cf0c-42c2-bccd-185b4648116b", "type": "debit", "created_at": "2022-10-21T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 3922} +{"id": "45e1d1da-ed78-427c-9138-5ea916a9786e", "type": "debit", "created_at": "2022-12-08T00:00:00", "document": "41", "payer": "Tamera Boone", "amount": 7895} +{"id": "f32ca6b3-c041-43bc-b5e4-25f9e068453c", "type": "credit", "created_at": "2022-05-17T00:00:00", "document": "86", "payer": "Robert Kraft", "amount": 1455} +{"id": "14313bc2-dd44-4f9e-a735-6a569c084de6", "type": "debit", "created_at": "2022-02-08T00:00:00", "document": "90", "payer": "Michael Griffin", "amount": 5200} +{"id": "6849f463-9eeb-405d-8bd4-0e337dc3a7ea", "type": "credit", "created_at": "2022-06-27T00:00:00", "document": "25", "payer": "Calvin Reid", "amount": 3276} +{"id": "72330e22-f08f-4007-a2c6-982ae69e5423", "type": "credit", "created_at": "2022-04-25T00:00:00", "document": "29", "payer": "Timothy Short", "amount": 2370} +{"id": "8ce6bc64-43b8-41d5-8a7a-2c42e9126f10", "type": "debit", "created_at": "2022-07-28T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 8736} +{"id": "594d20ce-c513-4a17-8683-b30b411416e8", "type": "credit", "created_at": "2022-09-10T00:00:00", "document": "76", "payer": "Megan Wallace", "amount": 7602} +{"id": "97927f5e-9df3-4149-a6a5-10698b906e86", "type": "credit", "created_at": "2022-10-04T00:00:00", "document": "91", "payer": "Gertrude Leishman", "amount": 9354} +{"id": "4375c507-84cd-4014-99eb-2f10251ba920", "type": "bank_slip", "created_at": "2022-12-16T00:00:00", "document": "97", "payer": "Marc Greer", "amount": 6965} +{"id": "e92ae355-da2a-4fb8-ae50-bc2515c9f99a", "type": "bank_slip", "created_at": "2022-11-28T00:00:00", "document": "39", "payer": "Brendan Pease", "amount": 8968} +{"id": "66779765-8504-4ca6-91e8-5aa24d090d2f", "type": "debit", "created_at": "2022-04-23T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 222} +{"id": "bfb27110-e85e-460b-94ca-cc24cd243b02", "type": "credit", "created_at": "2022-04-01T00:00:00", "document": "15", "payer": "James Blomdahl", "amount": 9338} +{"id": "8acfb98a-a226-4011-9c63-6238af73c3c8", "type": "debit", "created_at": "2022-10-06T00:00:00", "document": "55", "payer": "Ashley Beauchesne", "amount": 5439} +{"id": "f3b52c43-5a95-4595-8e18-1dd6347c020e", "type": "credit", "created_at": "2022-12-13T00:00:00", "document": "63", "payer": "Pearl Lemaire", "amount": 9093} +{"id": "17e7080a-188f-450b-a5b4-5880ea8467e2", "type": "bank_slip", "created_at": "2022-06-21T00:00:00", "document": "14", "payer": "Eleanore Hocutt", "amount": 4850} +{"id": "b1e38fcd-a586-42cb-a862-326df03e06c1", "type": "bank_slip", "created_at": "2022-02-16T00:00:00", "document": "59", "payer": "Elizabeth Robinson", "amount": 4205} +{"id": "dc765a5d-db73-4c08-86ba-09698e345f48", "type": "debit", "created_at": "2022-06-05T00:00:00", "document": "60", "payer": "Rachel York", "amount": 3020} +{"id": "45cc41a2-c3f1-4ffb-99ee-5bab70e5b22b", "type": "debit", "created_at": "2022-02-23T00:00:00", "document": "51", "payer": "Kenneth Stewart", "amount": 1805} +{"id": "73e13e3a-66fe-4795-b940-e2424db3aa02", "type": "debit", "created_at": "2022-07-25T00:00:00", "document": "34", "payer": "Sheila Ellard", "amount": 462} +{"id": "baf4bc6d-770a-4bc7-90f1-fd02b1723752", "type": "bank_slip", "created_at": "2022-11-07T00:00:00", "document": "27", "payer": "Devin Felt", "amount": 3930} +{"id": "bff12b0a-d51b-4d09-8460-776e665a4dab", "type": "bank_slip", "created_at": "2022-08-24T00:00:00", "document": "16", "payer": "Gary Kozak", "amount": 647} +{"id": "9820e6ce-0cb4-46fa-9c13-544b39db628c", "type": "bank_slip", "created_at": "2022-07-11T00:00:00", "document": "16", "payer": "Gary Kozak", "amount": 959} +{"id": "08bd67bb-6a6e-4ea8-86dc-ab75b620a342", "type": "bank_slip", "created_at": "2022-10-27T00:00:00", "document": "0", "payer": "Ruth Sheth", "amount": 4995} +{"id": "cf89f963-2bc1-4ea3-93f7-daf4339573d8", "type": "debit", "created_at": "2022-01-14T00:00:00", "document": "7", "payer": "Maria Bonney", "amount": 3283} +{"id": "fac7326c-06ab-4ee5-88cb-0b3f59a46ac0", "type": "credit", "created_at": "2022-07-20T00:00:00", "document": "34", "payer": "Sheila Ellard", "amount": 5154} +{"id": "6b1d5fde-777c-4f27-b9f9-1ac8a2cbc472", "type": "credit", "created_at": "2022-05-11T00:00:00", "document": "7", "payer": "Maria Bonney", "amount": 6818} +{"id": "9865286d-09fe-4f35-bb9a-34e739183947", "type": "credit", "created_at": "2022-07-05T00:00:00", "document": "86", "payer": "Robert Kraft", "amount": 6295} +{"id": "083de051-e82f-4ee5-992c-72f16cb483f7", "type": "debit", "created_at": "2022-06-08T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 7216} +{"id": "733196dd-154b-48d1-9890-38c7a35aa77d", "type": "bank_slip", "created_at": "2022-06-24T00:00:00", "document": "90", "payer": "Michael Griffin", "amount": 6531} +{"id": "98236706-11ce-4823-9c54-fea0241dd354", "type": "bank_slip", "created_at": "2022-09-08T00:00:00", "document": "98", "payer": "Elma Snapp", "amount": 878} +{"id": "771a03ea-c80d-44d0-94c2-654ea58a2d1b", "type": "credit", "created_at": "2022-07-13T00:00:00", "document": "97", "payer": "Marc Greer", "amount": 6634} +{"id": "c441a45e-9346-4e98-8732-f1bcc3c4faf4", "type": "bank_slip", "created_at": "2022-12-31T00:00:00", "document": "20", "payer": "Luis Moffett", "amount": 6256} +{"id": "82402476-6938-4d01-80be-520a67cdda71", "type": "debit", "created_at": "2022-01-18T00:00:00", "document": "84", "payer": "Rick Reid", "amount": 6607} +{"id": "be37c578-641f-401d-9d7c-c3c816e860b0", "type": "bank_slip", "created_at": "2022-01-29T00:00:00", "document": "40", "payer": "Charles Malik", "amount": 7802} +{"id": "19691dc1-0194-4df7-878e-f2de7495f114", "type": "bank_slip", "created_at": "2022-08-18T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 5179} +{"id": "e49819bc-8b0c-4b52-9371-4ded99107897", "type": "debit", "created_at": "2022-05-11T00:00:00", "document": "23", "payer": "Donald Lee", "amount": 62} +{"id": "fa494c73-f7df-4f23-90a7-9afadf23bda8", "type": "credit", "created_at": "2022-07-01T00:00:00", "document": "95", "payer": "Sarah Mcguire", "amount": 7268} +{"id": "75f73ebb-ad59-41fa-be2a-2ddd6e4b4f94", "type": "bank_slip", "created_at": "2022-03-14T00:00:00", "document": "35", "payer": "Maggie Auten", "amount": 5482} +{"id": "a3082785-e9d9-4edc-bd68-8489ee9c766f", "type": "bank_slip", "created_at": "2022-10-21T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 6031} +{"id": "3d1fbe06-5c12-49c0-8523-46554e57c528", "type": "bank_slip", "created_at": "2022-06-13T00:00:00", "document": "56", "payer": "Katherine Alexander", "amount": 6919} +{"id": "3436c17e-3ed7-47da-83ed-26509ae8e6b5", "type": "bank_slip", "created_at": "2022-10-18T00:00:00", "document": "44", "payer": "Kevin Parry", "amount": 1582} +{"id": "bf124060-14f2-4b60-82ef-6e12a3fbb36e", "type": "credit", "created_at": "2022-12-28T00:00:00", "document": "10", "payer": "Emanuel Robinson", "amount": 9453} +{"id": "59c91201-8a3d-473f-a966-26ccd0806523", "type": "debit", "created_at": "2022-12-09T00:00:00", "document": "88", "payer": "Gabrielle Santoyo", "amount": 4836} +{"id": "a6a51b11-4c9f-4e2c-8960-db4c0c83ff8a", "type": "credit", "created_at": "2022-05-13T00:00:00", "document": "67", "payer": "Wiley Goetz", "amount": 694} +{"id": "412b773c-9edf-4011-8751-89ec47758d64", "type": "bank_slip", "created_at": "2022-11-05T00:00:00", "document": "28", "payer": "Mark Williams", "amount": 5501} +{"id": "3c9eb77a-362a-4624-b141-5b5a8fcb3dea", "type": "credit", "created_at": "2022-01-16T00:00:00", "document": "7", "payer": "Maria Bonney", "amount": 7298} +{"id": "63db37a1-47ce-46eb-b406-d8e90cd07b7b", "type": "debit", "created_at": "2022-04-15T00:00:00", "document": "96", "payer": "Earl Morgan", "amount": 6250} +{"id": "92abe452-04fe-4a31-a8e9-2eb718c4a1a5", "type": "debit", "created_at": "2022-05-03T00:00:00", "document": "1", "payer": "Carl Teems", "amount": 4884} +{"id": "d0711ce4-3d14-4650-954d-cad79e28dbd6", "type": "bank_slip", "created_at": "2022-01-23T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 4024} +{"id": "3334b048-274f-4671-bbfc-602cc844fde2", "type": "credit", "created_at": "2022-06-03T00:00:00", "document": "44", "payer": "Kevin Parry", "amount": 6850} +{"id": "74d530eb-351d-4c93-a4e7-9415fa03c8ca", "type": "bank_slip", "created_at": "2022-02-10T00:00:00", "document": "35", "payer": "Maggie Auten", "amount": 9887} +{"id": "d1fe81fd-bfe4-4201-8637-628d9382a85a", "type": "bank_slip", "created_at": "2022-07-13T00:00:00", "document": "49", "payer": "Richard Isbell", "amount": 9063} +{"id": "3f3869c0-7bf9-4360-bcf2-32beefdf5934", "type": "credit", "created_at": "2022-01-23T00:00:00", "document": "13", "payer": "Janet Perry", "amount": 2655} +{"id": "5e9c1d4d-7f48-49d4-a82f-2de2d027135d", "type": "debit", "created_at": "2022-11-02T00:00:00", "document": "63", "payer": "Pearl Lemaire", "amount": 203} +{"id": "d376959e-8569-446b-9f17-66472465d45c", "type": "credit", "created_at": "2022-04-17T00:00:00", "document": "88", "payer": "Gabrielle Santoyo", "amount": 7486} +{"id": "3fcbdaa1-785a-4ec5-afd7-c6cfaa4729dc", "type": "debit", "created_at": "2022-05-28T00:00:00", "document": "90", "payer": "Michael Griffin", "amount": 8392} +{"id": "c3e6227e-39cc-4c96-83e2-480f4c9b4d2f", "type": "bank_slip", "created_at": "2022-07-19T00:00:00", "document": "60", "payer": "Rachel York", "amount": 5779} +{"id": "cb8a2a7d-42a8-42e0-9a8c-cfabac0cb106", "type": "debit", "created_at": "2022-09-12T00:00:00", "document": "44", "payer": "Kevin Parry", "amount": 9524} +{"id": "665fec6a-906f-4d7b-ae9f-61f967f8860d", "type": "debit", "created_at": "2022-12-02T00:00:00", "document": "0", "payer": "Ruth Sheth", "amount": 6179} +{"id": "7e98fcc3-a125-4aea-8646-04bb8815e1c3", "type": "credit", "created_at": "2022-05-23T00:00:00", "document": "0", "payer": "Ruth Sheth", "amount": 8979} +{"id": "4b63d7c7-aff1-4469-8eed-695dcc6ce6ea", "type": "credit", "created_at": "2022-06-30T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 9028} +{"id": "c5096fe2-5e01-4502-b14e-2c5136346d5f", "type": "debit", "created_at": "2022-03-13T00:00:00", "document": "4", "payer": "Marcia Griffin", "amount": 572} +{"id": "2f29485c-51b3-4b37-92e4-78511fbcb9e6", "type": "bank_slip", "created_at": "2022-09-10T00:00:00", "document": "83", "payer": "Filomena Suther", "amount": 3807} +{"id": "f72cb722-0d95-4bac-9ba7-326cc50f15c9", "type": "bank_slip", "created_at": "2022-04-18T00:00:00", "document": "16", "payer": "Gary Kozak", "amount": 4080} +{"id": "de446df8-ec1a-400d-9b96-53216b004c41", "type": "credit", "created_at": "2022-07-07T00:00:00", "document": "47", "payer": "Dustin Diller", "amount": 997} +{"id": "42914b75-6857-4210-b2fd-3083345a090f", "type": "credit", "created_at": "2022-01-02T00:00:00", "document": "39", "payer": "Brendan Pease", "amount": 1477} +{"id": "0f22de01-2ae2-465f-8056-cbb83c65f8f7", "type": "credit", "created_at": "2022-02-02T00:00:00", "document": "30", "payer": "Ronald Shurtleff", "amount": 4164} +{"id": "b9e770ea-5e13-4dba-b8d9-e264abdc50ae", "type": "bank_slip", "created_at": "2022-01-25T00:00:00", "document": "17", "payer": "Janice Coughlin", "amount": 1792} +{"id": "a50035d3-a660-4989-b327-36eec1b6ef28", "type": "bank_slip", "created_at": "2022-08-08T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 7616} +{"id": "bdf6854c-8254-4872-b76d-cfb306d0f358", "type": "credit", "created_at": "2022-01-23T00:00:00", "document": "66", "payer": "Kimberly Scott", "amount": 9736} +{"id": "68c32db9-373d-4ba8-a37a-dfe357306831", "type": "credit", "created_at": "2022-11-15T00:00:00", "document": "52", "payer": "Derek Corcoran", "amount": 3883} +{"id": "4554c1be-bd35-42ce-9827-87585a0b9210", "type": "bank_slip", "created_at": "2022-02-09T00:00:00", "document": "37", "payer": "Jane Olson", "amount": 2556} +{"id": "ea04dc87-2058-4048-8d0c-014ac7960455", "type": "bank_slip", "created_at": "2022-02-01T00:00:00", "document": "62", "payer": "Latasha Rubio", "amount": 2701} +{"id": "df480b98-e2b0-4fb0-bc97-e2974a182dbe", "type": "credit", "created_at": "2022-09-18T00:00:00", "document": "89", "payer": "Antonio Cooley", "amount": 7036} +{"id": "28dd086e-797f-4c2c-9c69-86bd391d93e7", "type": "credit", "created_at": "2022-01-22T00:00:00", "document": "62", "payer": "Latasha Rubio", "amount": 5125} +{"id": "e45f2980-c2af-4137-9007-75d21f3f40f9", "type": "bank_slip", "created_at": "2022-12-24T00:00:00", "document": "45", "payer": "Shanita Bergesen", "amount": 8184} +{"id": "f213cee2-ae11-4ebb-8743-4493e615448c", "type": "credit", "created_at": "2022-07-11T00:00:00", "document": "59", "payer": "Elizabeth Robinson", "amount": 7944} +{"id": "70cb0e3c-8e80-4151-b6f1-13656255e8ef", "type": "credit", "created_at": "2022-09-05T00:00:00", "document": "1", "payer": "Carl Teems", "amount": 6726} +{"id": "e9d9bc3e-02f9-4d51-b604-8ee37775833e", "type": "debit", "created_at": "2022-12-20T00:00:00", "document": "75", "payer": "Edie Callam", "amount": 4963} +{"id": "934e183d-8fa8-4dc3-984e-ac9f1fadcb6c", "type": "debit", "created_at": "2022-10-10T00:00:00", "document": "71", "payer": "Florence Henderson", "amount": 1242} +{"id": "43f82a2c-4ca5-4401-b1ed-ddc09477de8f", "type": "bank_slip", "created_at": "2022-05-14T00:00:00", "document": "91", "payer": "Gertrude Leishman", "amount": 6829} +{"id": "ef37cc1e-e13e-4970-9a5d-f448a903e69e", "type": "credit", "created_at": "2022-08-18T00:00:00", "document": "95", "payer": "Sarah Mcguire", "amount": 4561} +{"id": "7fb2cc12-6ae7-484e-aef6-e0a45a47ca83", "type": "credit", "created_at": "2022-12-22T00:00:00", "document": "24", "payer": "Susan Bostic", "amount": 440} +{"id": "54424be3-90ff-4b60-a8fc-f31e6f586c14", "type": "credit", "created_at": "2022-06-19T00:00:00", "document": "16", "payer": "Gary Kozak", "amount": 9616} +{"id": "9b2e9e29-30a8-48ac-a45b-fef2f0f4356a", "type": "credit", "created_at": "2022-03-23T00:00:00", "document": "90", "payer": "Michael Griffin", "amount": 1750} +{"id": "35ee566f-b38b-44c4-8113-96af53ed1b0c", "type": "credit", "created_at": "2022-06-25T00:00:00", "document": "41", "payer": "Tamera Boone", "amount": 4950} +{"id": "b2cf74c6-6195-4a25-8f30-66e34db6adb0", "type": "credit", "created_at": "2022-04-22T00:00:00", "document": "47", "payer": "Dustin Diller", "amount": 6269} +{"id": "4babfc8a-36eb-46d0-9b37-aef39111bbc6", "type": "debit", "created_at": "2022-11-01T00:00:00", "document": "5", "payer": "Paula Spencer", "amount": 8719} +{"id": "bd1b44f9-428b-44d2-9b38-4d5c46a93a76", "type": "credit", "created_at": "2022-04-03T00:00:00", "document": "20", "payer": "Luis Moffett", "amount": 5112} +{"id": "4f8ce0d7-a62c-4ea3-9165-68c2640d8169", "type": "debit", "created_at": "2022-12-16T00:00:00", "document": "96", "payer": "Earl Morgan", "amount": 2276} +{"id": "b4e7ff8f-2dc8-45e7-9b3e-ddf63b4134e1", "type": "debit", "created_at": "2022-12-22T00:00:00", "document": "85", "payer": "Susan Wolcott", "amount": 1705} +{"id": "65a2fa21-826a-46fa-90e7-fa70a76b61e8", "type": "credit", "created_at": "2022-10-26T00:00:00", "document": "29", "payer": "Timothy Short", "amount": 6906} +{"id": "b0d1bbec-a21b-45c4-9789-300ccb5feaf9", "type": "credit", "created_at": "2022-11-27T00:00:00", "document": "31", "payer": "Ridebito Little", "amount": 2064} +{"id": "3af2ebea-df2f-4d33-879a-1c9db68645e0", "type": "debit", "created_at": "2022-12-22T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 2217} +{"id": "d8791561-c081-403e-abba-dbfeaad0a189", "type": "bank_slip", "created_at": "2022-12-08T00:00:00", "document": "7", "payer": "Maria Bonney", "amount": 5159} +{"id": "57207b32-7e91-4ea3-b37e-4f614fa66cb4", "type": "credit", "created_at": "2022-12-03T00:00:00", "document": "55", "payer": "Ashley Beauchesne", "amount": 5158} +{"id": "dfbc28f7-bcdf-425c-a96c-ba3bdf368165", "type": "debit", "created_at": "2022-09-22T00:00:00", "document": "70", "payer": "Patrick Davis", "amount": 8307} +{"id": "7a8ecf99-8f3e-4f6d-b1ce-9f7c26408e04", "type": "debit", "created_at": "2022-10-26T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 6268} +{"id": "476bd74f-039c-426f-8de7-635543ec124a", "type": "credit", "created_at": "2022-02-06T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 3854} +{"id": "6aa8f3e9-30da-4592-bc46-a1850ba20dec", "type": "bank_slip", "created_at": "2022-12-02T00:00:00", "document": "61", "payer": "Ladonna Cooper", "amount": 1349} +{"id": "efa65340-c6f2-4cbf-af44-f99f4d8b06e9", "type": "bank_slip", "created_at": "2022-02-25T00:00:00", "document": "21", "payer": "Richard Duckett", "amount": 4866} +{"id": "dbe2d7d0-47fd-4462-ab43-165b8683add3", "type": "debit", "created_at": "2022-05-11T00:00:00", "document": "15", "payer": "James Blomdahl", "amount": 295} +{"id": "3e449b5a-b57c-49d2-a377-b5ae8f5c51ec", "type": "bank_slip", "created_at": "2022-02-02T00:00:00", "document": "58", "payer": "Erin Rhoads", "amount": 2678} +{"id": "c5c549b2-1164-4931-892f-b36322d89a4f", "type": "debit", "created_at": "2022-01-01T00:00:00", "document": "17", "payer": "Janice Coughlin", "amount": 138} +{"id": "c91bb090-3a61-4dc1-bac8-c4ff0dd51796", "type": "debit", "created_at": "2022-09-08T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 4246} +{"id": "d03f52d9-dca7-4697-9931-85768e97a846", "type": "debit", "created_at": "2022-08-05T00:00:00", "document": "60", "payer": "Rachel York", "amount": 3695} +{"id": "55b0bd9c-625d-4584-8c32-a044c74b2073", "type": "debit", "created_at": "2022-09-10T00:00:00", "document": "22", "payer": "Noemi Mcintyre", "amount": 8593} +{"id": "28b82939-9e55-4b47-80fe-fbcf3cdcd89a", "type": "debit", "created_at": "2022-03-31T00:00:00", "document": "33", "payer": "Charlotte Marczak", "amount": 1573} +{"id": "e923c9bb-4ccf-4cad-b310-263c415bb34a", "type": "credit", "created_at": "2022-06-08T00:00:00", "document": "86", "payer": "Robert Kraft", "amount": 183} +{"id": "af9b2be2-86f7-411f-ae65-d05f1f4144ef", "type": "bank_slip", "created_at": "2022-01-13T00:00:00", "document": "31", "payer": "Ridebito Little", "amount": 1633} +{"id": "d8f291f5-658f-4668-b6e7-dc3a8a6f3e53", "type": "credit", "created_at": "2022-12-23T00:00:00", "document": "49", "payer": "Richard Isbell", "amount": 5380} +{"id": "a56f292f-8bb2-40c9-8ce2-a1ab0fbda5f1", "type": "bank_slip", "created_at": "2022-09-24T00:00:00", "document": "31", "payer": "Ridebito Little", "amount": 7181} +{"id": "c34c6dff-fd50-4c07-af03-b54bb43f0f35", "type": "bank_slip", "created_at": "2022-03-09T00:00:00", "document": "77", "payer": "Michael Fultz", "amount": 1356} +{"id": "f5814200-cfa1-4a4e-b9ab-207bcf277146", "type": "bank_slip", "created_at": "2022-03-19T00:00:00", "document": "10", "payer": "Emanuel Robinson", "amount": 9536} +{"id": "95b4547b-4128-480a-b2e7-331c4c5190fe", "type": "credit", "created_at": "2022-11-27T00:00:00", "document": "14", "payer": "Eleanore Hocutt", "amount": 2921} +{"id": "ec77b16a-a67f-4bf6-b167-7a2895176b6e", "type": "bank_slip", "created_at": "2022-09-07T00:00:00", "document": "50", "payer": "Karen Lewis", "amount": 8080} +{"id": "e60d958a-a646-4a3a-9ba5-5394d38cc260", "type": "bank_slip", "created_at": "2022-09-15T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 758} +{"id": "25aa27c9-f66c-4161-b94a-3d621080867a", "type": "bank_slip", "created_at": "2022-04-26T00:00:00", "document": "4", "payer": "Marcia Griffin", "amount": 4253} +{"id": "42af1641-b45a-4385-8dc6-7b14c26b7cf7", "type": "bank_slip", "created_at": "2022-09-11T00:00:00", "document": "34", "payer": "Sheila Ellard", "amount": 3507} +{"id": "36e2bcc7-f96d-4205-8dac-17c669807373", "type": "credit", "created_at": "2022-03-20T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 7868} +{"id": "acb67761-c14e-4d04-b222-ff7a2681c475", "type": "debit", "created_at": "2022-06-08T00:00:00", "document": "86", "payer": "Robert Kraft", "amount": 9018} +{"id": "a7fd9162-0539-4b3a-9ec7-5fce8a701fd5", "type": "credit", "created_at": "2022-07-28T00:00:00", "document": "97", "payer": "Marc Greer", "amount": 3909} +{"id": "5f0ebe16-fabd-4f2e-85a1-a849c0a9e985", "type": "debit", "created_at": "2022-06-19T00:00:00", "document": "74", "payer": "Norma Brumit", "amount": 4583} +{"id": "585c2b57-c4e2-42be-81d3-2b5866aa8643", "type": "credit", "created_at": "2022-03-13T00:00:00", "document": "98", "payer": "Elma Snapp", "amount": 2715} +{"id": "11b40cea-0be5-4be1-a6ee-e14dfe31a1a6", "type": "credit", "created_at": "2022-11-19T00:00:00", "document": "65", "payer": "William Boxer", "amount": 6516} +{"id": "a8aa09e0-2087-4b39-8515-ebe81a500f01", "type": "debit", "created_at": "2022-09-23T00:00:00", "document": "39", "payer": "Brendan Pease", "amount": 1732} +{"id": "6d0a0a8e-8417-4a36-ada2-4e69e084b349", "type": "credit", "created_at": "2022-01-31T00:00:00", "document": "74", "payer": "Norma Brumit", "amount": 2676} +{"id": "84c91a0d-8962-428d-ba0f-dc30838f07b2", "type": "bank_slip", "created_at": "2022-02-01T00:00:00", "document": "83", "payer": "Filomena Suther", "amount": 6965} +{"id": "7fb30b49-b2d9-4612-86c4-ebf6f3ddfe83", "type": "bank_slip", "created_at": "2022-08-25T00:00:00", "document": "28", "payer": "Mark Williams", "amount": 5646} +{"id": "9525530d-145b-4f61-a8cc-42c67eca402d", "type": "credit", "created_at": "2022-06-29T00:00:00", "document": "18", "payer": "Armida Kostrzewa", "amount": 6797} +{"id": "e1a74e5a-03fb-4633-87eb-535a2868addd", "type": "credit", "created_at": "2022-12-10T00:00:00", "document": "89", "payer": "Antonio Cooley", "amount": 6366} +{"id": "caf51cb0-9701-475f-98bb-3f859d5d5c91", "type": "bank_slip", "created_at": "2022-12-08T00:00:00", "document": "32", "payer": "Barbara Harris", "amount": 4999} +{"id": "8ae97a5a-d2c8-4ce4-99ce-2f9553fcaee7", "type": "debit", "created_at": "2022-11-25T00:00:00", "document": "51", "payer": "Kenneth Stewart", "amount": 4408} +{"id": "002d6546-46fd-4e91-ba67-cba45c8d175d", "type": "bank_slip", "created_at": "2022-01-07T00:00:00", "document": "60", "payer": "Rachel York", "amount": 8978} +{"id": "73a77f94-4d97-4c8f-bb9f-72774a1f13aa", "type": "bank_slip", "created_at": "2022-05-23T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 1836} +{"id": "194741b3-64bd-489e-81f2-14e6da41a301", "type": "debit", "created_at": "2022-05-09T00:00:00", "document": "15", "payer": "James Blomdahl", "amount": 8286} +{"id": "e3f033dc-aa8c-4bc9-a000-97afe843c540", "type": "credit", "created_at": "2022-04-23T00:00:00", "document": "51", "payer": "Kenneth Stewart", "amount": 9289} +{"id": "4d3054b1-4922-4eef-bb67-863552f3b76a", "type": "debit", "created_at": "2022-08-22T00:00:00", "document": "6", "payer": "John Dickerson", "amount": 2166} +{"id": "7b6c2166-d709-436e-a824-63e7835acfc1", "type": "bank_slip", "created_at": "2022-10-18T00:00:00", "document": "63", "payer": "Pearl Lemaire", "amount": 9836} +{"id": "85f77ea6-2d75-46e8-93d7-7c19a5d3498c", "type": "credit", "created_at": "2022-07-16T00:00:00", "document": "50", "payer": "Karen Lewis", "amount": 6112} +{"id": "ce1fb022-e6b5-4126-8219-cbbd6e2b905a", "type": "bank_slip", "created_at": "2022-01-03T00:00:00", "document": "98", "payer": "Elma Snapp", "amount": 1785} +{"id": "2a2a30db-3c27-47a7-b510-14fb7c54d417", "type": "bank_slip", "created_at": "2022-05-04T00:00:00", "document": "62", "payer": "Latasha Rubio", "amount": 6575} +{"id": "d5508c30-2193-494d-9b3c-6bc560ef7d9c", "type": "credit", "created_at": "2022-10-10T00:00:00", "document": "58", "payer": "Erin Rhoads", "amount": 1370} +{"id": "45a8f073-d40b-4c92-bfdc-a64fab60d08d", "type": "credit", "created_at": "2022-04-15T00:00:00", "document": "93", "payer": "George Lesane", "amount": 902} +{"id": "a56a619b-fc85-4f99-8643-83828557cea2", "type": "debit", "created_at": "2022-01-25T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 1345} +{"id": "049ea531-8385-4b3a-87c7-2f66830fd9aa", "type": "debit", "created_at": "2022-05-13T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 5622} +{"id": "0868437e-080a-4f34-9b2c-df37cc77acd0", "type": "bank_slip", "created_at": "2022-11-12T00:00:00", "document": "72", "payer": "Shirley Digiovanni", "amount": 2834} +{"id": "80622b63-23df-4606-aa83-30e3ed4223d7", "type": "debit", "created_at": "2022-12-05T00:00:00", "document": "30", "payer": "Ronald Shurtleff", "amount": 9594} +{"id": "dfae87a1-42c8-49af-85d2-d10375b28139", "type": "credit", "created_at": "2022-08-02T00:00:00", "document": "98", "payer": "Elma Snapp", "amount": 9487} +{"id": "6cd5c547-5dae-4959-ac62-659e1756b3c1", "type": "credit", "created_at": "2022-02-06T00:00:00", "document": "40", "payer": "Charles Malik", "amount": 4199} +{"id": "ae0075f8-2fc7-4d79-8c59-d3472551093b", "type": "credit", "created_at": "2022-03-11T00:00:00", "document": "3", "payer": "Conrad Hardin", "amount": 8215} +{"id": "95816dfe-e28a-499f-a605-c117de7cb89b", "type": "bank_slip", "created_at": "2022-05-16T00:00:00", "document": "12", "payer": "Susan Woodward", "amount": 2405} +{"id": "fb5f0cbd-0842-4cf3-b6b1-f3e5f48c6a83", "type": "credit", "created_at": "2022-01-26T00:00:00", "document": "99", "payer": "Mark Seidel", "amount": 9178} +{"id": "6b0d3a74-7a1e-490e-aadd-3ac570f55524", "type": "debit", "created_at": "2022-09-10T00:00:00", "document": "6", "payer": "John Dickerson", "amount": 2260} +{"id": "018f235b-f48e-4b88-8f06-6334a31d4996", "type": "bank_slip", "created_at": "2022-07-08T00:00:00", "document": "20", "payer": "Luis Moffett", "amount": 6218} +{"id": "1a3394bf-cc47-4987-b08b-2808a2c8430d", "type": "credit", "created_at": "2022-05-14T00:00:00", "document": "67", "payer": "Wiley Goetz", "amount": 3816} +{"id": "14ea3cb8-eb4c-4e14-a1a6-8d47bdc7c251", "type": "credit", "created_at": "2022-05-21T00:00:00", "document": "97", "payer": "Marc Greer", "amount": 8543} +{"id": "e0509b13-678b-41e5-9d2c-0f2966e30b45", "type": "bank_slip", "created_at": "2022-01-04T00:00:00", "document": "5", "payer": "Paula Spencer", "amount": 8772} +{"id": "d9bc1e55-b4a4-4445-908b-bd939f4b2ccf", "type": "credit", "created_at": "2022-11-28T00:00:00", "document": "12", "payer": "Susan Woodward", "amount": 8767} +{"id": "d9c0028e-e252-406f-98e9-d4aa426687be", "type": "debit", "created_at": "2022-12-12T00:00:00", "document": "80", "payer": "Joyce Wimberly", "amount": 8990} +{"id": "34935509-387b-46c8-818d-6f511fadcda8", "type": "bank_slip", "created_at": "2022-03-31T00:00:00", "document": "36", "payer": "Elfreda Garza", "amount": 2026} +{"id": "7d7f280b-0307-4745-a917-af368c545128", "type": "bank_slip", "created_at": "2022-03-12T00:00:00", "document": "28", "payer": "Mark Williams", "amount": 1685} +{"id": "18394a1c-ba7b-4160-9156-ccb4e5326e24", "type": "bank_slip", "created_at": "2022-12-17T00:00:00", "document": "88", "payer": "Gabrielle Santoyo", "amount": 4015} +{"id": "5155a48a-b361-437d-a25e-098265022373", "type": "debit", "created_at": "2022-07-04T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 9492} +{"id": "b1b6b5b7-a26e-4579-bff9-ea97800598bf", "type": "credit", "created_at": "2022-10-06T00:00:00", "document": "41", "payer": "Tamera Boone", "amount": 4942} +{"id": "67d798a6-4d6a-4701-9fa4-007c2aa4ed4c", "type": "debit", "created_at": "2022-02-23T00:00:00", "document": "13", "payer": "Janet Perry", "amount": 3145} +{"id": "89782482-abeb-40d5-a98d-40c827ab1fe7", "type": "credit", "created_at": "2022-10-02T00:00:00", "document": "60", "payer": "Rachel York", "amount": 4253} +{"id": "e2d1dde9-89ca-4597-901e-932e879c1a84", "type": "credit", "created_at": "2022-03-26T00:00:00", "document": "65", "payer": "William Boxer", "amount": 5407} +{"id": "7e8283d7-96f3-42eb-90b8-bb1a820d5a59", "type": "credit", "created_at": "2022-11-16T00:00:00", "document": "12", "payer": "Susan Woodward", "amount": 6274} +{"id": "d1fb3805-6a78-4ceb-bbc5-917ee6997131", "type": "bank_slip", "created_at": "2022-05-28T00:00:00", "document": "86", "payer": "Robert Kraft", "amount": 9223} +{"id": "3f4e46d4-3fbf-4d5f-9477-fb9bb5610481", "type": "bank_slip", "created_at": "2022-02-08T00:00:00", "document": "13", "payer": "Janet Perry", "amount": 3204} +{"id": "164a911d-c24f-4659-9386-68270395a221", "type": "bank_slip", "created_at": "2022-07-14T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 2352} +{"id": "892d1cb5-7719-4be7-85f4-82c487e79972", "type": "bank_slip", "created_at": "2022-03-19T00:00:00", "document": "15", "payer": "James Blomdahl", "amount": 6525} +{"id": "0223bb00-5a41-4464-8c98-54adfeb441f7", "type": "debit", "created_at": "2022-08-13T00:00:00", "document": "34", "payer": "Sheila Ellard", "amount": 5480} +{"id": "580dfaa4-546a-43b0-b4e8-8c61e28dd048", "type": "debit", "created_at": "2022-10-01T00:00:00", "document": "2", "payer": "Ella Tatum", "amount": 1976} +{"id": "925d0781-353a-43f5-bfd6-58dbf9ed0a94", "type": "debit", "created_at": "2022-07-01T00:00:00", "document": "83", "payer": "Filomena Suther", "amount": 5222} +{"id": "b2b3591f-8af6-44d0-8321-2e509e74e725", "type": "bank_slip", "created_at": "2022-01-17T00:00:00", "document": "6", "payer": "John Dickerson", "amount": 5929} +{"id": "91664d1e-a810-4f29-aabb-fd673f3c5cdf", "type": "debit", "created_at": "2022-06-12T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 6048} +{"id": "283ea219-1329-47f6-8331-277f0fef2f1d", "type": "credit", "created_at": "2022-06-12T00:00:00", "document": "88", "payer": "Gabrielle Santoyo", "amount": 8187} +{"id": "add68385-c8c0-4664-92b2-df245a1f5497", "type": "credit", "created_at": "2022-01-31T00:00:00", "document": "63", "payer": "Pearl Lemaire", "amount": 3645} +{"id": "d3ee74de-5592-470e-a400-a5f8e2d0ddfd", "type": "debit", "created_at": "2022-02-17T00:00:00", "document": "29", "payer": "Timothy Short", "amount": 3906} +{"id": "8df655d0-a4a6-4560-a937-2b94089ed539", "type": "bank_slip", "created_at": "2022-03-15T00:00:00", "document": "95", "payer": "Sarah Mcguire", "amount": 8759} +{"id": "27577477-6619-45df-92f4-82d2a6dde973", "type": "credit", "created_at": "2022-03-22T00:00:00", "document": "15", "payer": "James Blomdahl", "amount": 8766} +{"id": "746b1aa8-8aeb-4412-ae9a-66a0436c308a", "type": "bank_slip", "created_at": "2022-02-02T00:00:00", "document": "10", "payer": "Emanuel Robinson", "amount": 1640} +{"id": "721904a9-dfbe-4738-b361-322dea29d473", "type": "credit", "created_at": "2022-05-24T00:00:00", "document": "63", "payer": "Pearl Lemaire", "amount": 9352} +{"id": "b04ae878-e67c-4cd2-985c-ec56fb728648", "type": "bank_slip", "created_at": "2022-07-29T00:00:00", "document": "20", "payer": "Luis Moffett", "amount": 4055} +{"id": "f782f1e2-3c4d-4c5b-b2ca-af3c1540dc09", "type": "debit", "created_at": "2022-12-25T00:00:00", "document": "46", "payer": "Shaunda Gallegos", "amount": 8207} +{"id": "3adabd10-6ea3-4548-bab2-0464cf689028", "type": "debit", "created_at": "2022-03-16T00:00:00", "document": "29", "payer": "Timothy Short", "amount": 6310} +{"id": "2cba25d1-ab2a-4bdc-8597-5085114b23ec", "type": "debit", "created_at": "2022-12-21T00:00:00", "document": "25", "payer": "Calvin Reid", "amount": 1425} +{"id": "11e1d791-492f-413c-94bf-05550a98b142", "type": "debit", "created_at": "2022-01-29T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 5373} +{"id": "71ce76cf-940c-4ae4-8fa3-356cd75ee180", "type": "credit", "created_at": "2022-05-08T00:00:00", "document": "21", "payer": "Richard Duckett", "amount": 7118} +{"id": "4f79b3d9-66c8-4a4d-ac7a-94c2f2a35daf", "type": "debit", "created_at": "2022-07-29T00:00:00", "document": "13", "payer": "Janet Perry", "amount": 4515} +{"id": "bdda3c70-c00c-4f32-bea9-8a65e28b2228", "type": "bank_slip", "created_at": "2022-09-19T00:00:00", "document": "40", "payer": "Charles Malik", "amount": 2617} +{"id": "103dd83a-49e3-4f9d-a290-f32d9b80c9da", "type": "bank_slip", "created_at": "2022-03-05T00:00:00", "document": "94", "payer": "Rupert Peterman", "amount": 8398} +{"id": "22241bad-30a8-4d4c-b625-98bd17d9aec5", "type": "bank_slip", "created_at": "2022-05-30T00:00:00", "document": "40", "payer": "Charles Malik", "amount": 8884} +{"id": "ad07dc66-bbd2-4c6b-b66f-b230eea0009b", "type": "credit", "created_at": "2022-01-04T00:00:00", "document": "48", "payer": "Lori Carter", "amount": 6773} +{"id": "a7eae518-ce66-41b8-87c4-07732ee37f04", "type": "credit", "created_at": "2022-04-19T00:00:00", "document": "41", "payer": "Tamera Boone", "amount": 9226} +{"id": "6671ef5d-a6b1-4a24-b4a0-007c2bf6a7a4", "type": "debit", "created_at": "2022-02-18T00:00:00", "document": "99", "payer": "Mark Seidel", "amount": 1566} +{"id": "29343b43-1469-4df4-b8d8-1cd405615e24", "type": "credit", "created_at": "2022-03-26T00:00:00", "document": "26", "payer": "Robert Krupp", "amount": 7622} +{"id": "7aa494ec-ccda-409f-ba1a-f359bb5cbd3a", "type": "bank_slip", "created_at": "2022-01-21T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 6001} +{"id": "a7d88c91-e76b-4d7f-a612-74c2ce7520f6", "type": "credit", "created_at": "2022-02-14T00:00:00", "document": "31", "payer": "Ridebito Little", "amount": 7148} +{"id": "e8a9018f-6ee1-48d8-947f-6e8fa34e906c", "type": "bank_slip", "created_at": "2022-04-13T00:00:00", "document": "9", "payer": "Connie Randall", "amount": 2448} +{"id": "e52111a8-2a93-4ca1-9ee7-d40cac01e54a", "type": "bank_slip", "created_at": "2022-05-21T00:00:00", "document": "55", "payer": "Ashley Beauchesne", "amount": 133} +{"id": "5f9919db-2a4e-4088-9d29-a08b65dab3fb", "type": "credit", "created_at": "2022-10-06T00:00:00", "document": "43", "payer": "Gary Jensen", "amount": 7591} +{"id": "70725ddf-78da-472e-81c8-c1537b7c2f4b", "type": "credit", "created_at": "2022-08-02T00:00:00", "document": "61", "payer": "Ladonna Cooper", "amount": 9429} +{"id": "66146035-82ae-40c2-a12e-a85725da0661", "type": "credit", "created_at": "2022-10-20T00:00:00", "document": "11", "payer": "Jenny Jensen", "amount": 9908} +{"id": "ca897eb4-16ff-42fe-a417-203d912dcbe1", "type": "bank_slip", "created_at": "2022-04-13T00:00:00", "document": "54", "payer": "Carmela Ho", "amount": 9622} +{"id": "5b951992-0e05-4ea7-bbaf-6ab640d71cc4", "type": "bank_slip", "created_at": "2022-01-13T00:00:00", "document": "88", "payer": "Gabrielle Santoyo", "amount": 5952} +{"id": "ab86965d-f12f-482a-b1a0-a645a78fd02a", "type": "credit", "created_at": "2022-04-22T00:00:00", "document": "83", "payer": "Filomena Suther", "amount": 2112} +{"id": "e0a9d09d-2867-40b4-8891-84e1507b5905", "type": "credit", "created_at": "2022-12-08T00:00:00", "document": "57", "payer": "David Landry", "amount": 9061} +{"id": "038a1b7d-ae5d-43b8-a00a-357fb583970d", "type": "credit", "created_at": "2022-10-26T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 3849} +{"id": "0c511e8d-baf7-461c-b05d-5e095bd56411", "type": "debit", "created_at": "2022-09-05T00:00:00", "document": "95", "payer": "Sarah Mcguire", "amount": 9218} +{"id": "a608e21b-c779-4e6f-abc2-6fd5c5d1272c", "type": "debit", "created_at": "2022-03-26T00:00:00", "document": "90", "payer": "Michael Griffin", "amount": 1062} +{"id": "c113b25d-c6dd-4c8d-b842-05579a409cbb", "type": "bank_slip", "created_at": "2022-07-31T00:00:00", "document": "68", "payer": "Pauline Marcum", "amount": 3936} +{"id": "d741ad19-e007-42c9-9825-65e2411f006a", "type": "debit", "created_at": "2022-06-04T00:00:00", "document": "96", "payer": "Earl Morgan", "amount": 325} +{"id": "6d734a1b-58d2-48c4-8eea-5629aee365d3", "type": "credit", "created_at": "2022-08-12T00:00:00", "document": "75", "payer": "Edie Callam", "amount": 7658} +{"id": "bd053a27-773f-45bd-a04f-d6c37bf8734b", "type": "bank_slip", "created_at": "2022-04-27T00:00:00", "document": "7", "payer": "Maria Bonney", "amount": 446} +{"id": "38b60a1c-14f3-4c7c-bec2-3bb8259c3d55", "type": "debit", "created_at": "2022-08-19T00:00:00", "document": "62", "payer": "Latasha Rubio", "amount": 9295} +{"id": "34e1ef9e-8381-4fd3-872f-78932c3c2213", "type": "credit", "created_at": "2022-06-19T00:00:00", "document": "66", "payer": "Kimberly Scott", "amount": 3289} +{"id": "7ec1f52b-b9e0-4f7d-ac61-223515b7fbcb", "type": "debit", "created_at": "2022-09-15T00:00:00", "document": "57", "payer": "David Landry", "amount": 8492} +{"id": "a13bdec1-4d59-4625-b153-cc998ca426f9", "type": "bank_slip", "created_at": "2022-05-09T00:00:00", "document": "93", "payer": "George Lesane", "amount": 813} +{"id": "9a44edbd-a00f-4abc-ae8b-033b6ad29549", "type": "bank_slip", "created_at": "2022-07-05T00:00:00", "document": "29", "payer": "Timothy Short", "amount": 230} +{"id": "5a32a6f7-7883-46e5-9434-902aff911077", "type": "credit", "created_at": "2022-09-16T00:00:00", "document": "5", "payer": "Paula Spencer", "amount": 877} +{"id": "dfab8323-9f20-423b-b8ba-c229a0c7f73c", "type": "credit", "created_at": "2022-12-18T00:00:00", "document": "51", "payer": "Kenneth Stewart", "amount": 5263} +{"id": "5fb02235-0205-405b-9da8-7ce38b995032", "type": "bank_slip", "created_at": "2022-02-05T00:00:00", "document": "3", "payer": "Conrad Hardin", "amount": 7529} +{"id": "20ce820d-768b-4297-8c6a-fe44a2569062", "type": "credit", "created_at": "2022-05-21T00:00:00", "document": "57", "payer": "David Landry", "amount": 4038} +{"id": "0fb080db-e77b-4ec1-a1d1-ca8a9f81ddfa", "type": "credit", "created_at": "2022-05-05T00:00:00", "document": "11", "payer": "Jenny Jensen", "amount": 1478} +{"id": "3746be86-2d4c-431b-9c02-940efa02c22d", "type": "bank_slip", "created_at": "2022-07-21T00:00:00", "document": "30", "payer": "Ronald Shurtleff", "amount": 1758} +{"id": "9a8eda79-16c8-4e5e-b781-c0ac342512a6", "type": "credit", "created_at": "2022-07-16T00:00:00", "document": "31", "payer": "Ridebito Little", "amount": 5558} +{"id": "b5248704-1ab9-441d-994c-b16a339c09bc", "type": "credit", "created_at": "2022-02-22T00:00:00", "document": "92", "payer": "Amber Hudson", "amount": 8641} +{"id": "5e16fdcd-d393-4a49-a511-dc8f277a0b75", "type": "bank_slip", "created_at": "2022-07-30T00:00:00", "document": "62", "payer": "Latasha Rubio", "amount": 9571} +{"id": "c2bfad88-7fb9-41f2-9139-96a898816c7d", "type": "credit", "created_at": "2022-02-26T00:00:00", "document": "16", "payer": "Gary Kozak", "amount": 2001} +{"id": "0e79b835-5b04-4f63-ab05-6d8415cb6e60", "type": "credit", "created_at": "2022-12-27T00:00:00", "document": "26", "payer": "Robert Krupp", "amount": 3864} +{"id": "d9c1dd36-74ba-45d8-a7ef-f7bc13a7f48b", "type": "credit", "created_at": "2022-04-19T00:00:00", "document": "11", "payer": "Jenny Jensen", "amount": 120} +{"id": "cf214a78-6cbd-4e0c-8d5b-f90942dfaaf4", "type": "bank_slip", "created_at": "2022-12-17T00:00:00", "document": "14", "payer": "Eleanore Hocutt", "amount": 5578} +{"id": "6bec32a2-4c33-4444-b2b4-de35b33cd16b", "type": "credit", "created_at": "2022-07-13T00:00:00", "document": "28", "payer": "Mark Williams", "amount": 5314} +{"id": "e2171948-f3dc-4d93-b2ec-91e315beb790", "type": "debit", "created_at": "2022-02-23T00:00:00", "document": "45", "payer": "Shanita Bergesen", "amount": 5599} +{"id": "3b7361c0-c275-433b-b6d3-bc2dbf12408c", "type": "debit", "created_at": "2022-03-14T00:00:00", "document": "32", "payer": "Barbara Harris", "amount": 6188} +{"id": "7773d0c9-4aaf-4a7e-b345-9d92fb8271ab", "type": "credit", "created_at": "2022-06-28T00:00:00", "document": "51", "payer": "Kenneth Stewart", "amount": 3573} +{"id": "0f3a61d0-477e-4a8e-8a95-93db63d4fdb7", "type": "bank_slip", "created_at": "2022-12-10T00:00:00", "document": "20", "payer": "Luis Moffett", "amount": 3326} +{"id": "51d081c9-7a4a-408b-b197-82a4f5ae8753", "type": "bank_slip", "created_at": "2022-06-24T00:00:00", "document": "48", "payer": "Lori Carter", "amount": 7334} +{"id": "2d72f135-a82d-425b-961b-0bd54330ad8c", "type": "bank_slip", "created_at": "2022-04-26T00:00:00", "document": "29", "payer": "Timothy Short", "amount": 1778} +{"id": "01522cb7-c14e-4e37-b797-8d81488ffed5", "type": "debit", "created_at": "2022-11-28T00:00:00", "document": "37", "payer": "Jane Olson", "amount": 7805} +{"id": "439f70b9-fd9e-403f-8c1e-b3ac0cc6a745", "type": "credit", "created_at": "2022-03-13T00:00:00", "document": "87", "payer": "Emily Cockerill", "amount": 5486} +{"id": "a8aedef6-4a6d-4021-94b6-f392de26c334", "type": "bank_slip", "created_at": "2022-12-08T00:00:00", "document": "17", "payer": "Janice Coughlin", "amount": 8434} +{"id": "defe464a-246d-4c08-94e7-a15c11e91aad", "type": "debit", "created_at": "2022-11-17T00:00:00", "document": "65", "payer": "William Boxer", "amount": 2274} +{"id": "e260af4b-13c4-4e8f-bff9-765151865ba7", "type": "debit", "created_at": "2022-11-17T00:00:00", "document": "39", "payer": "Brendan Pease", "amount": 3105} +{"id": "19d17d8f-a6e7-4e08-9dc1-79d92476e11e", "type": "credit", "created_at": "2022-08-24T00:00:00", "document": "2", "payer": "Ella Tatum", "amount": 7972} +{"id": "c37827c5-5e67-4a28-ad75-40702ae8c6dd", "type": "debit", "created_at": "2022-11-16T00:00:00", "document": "90", "payer": "Michael Griffin", "amount": 8600} +{"id": "36391409-7999-41c9-ac53-07a9cb54a60f", "type": "bank_slip", "created_at": "2022-11-13T00:00:00", "document": "13", "payer": "Janet Perry", "amount": 2684} +{"id": "e1cec55e-bd63-4d7d-9916-3b65d905cdf6", "type": "credit", "created_at": "2022-08-21T00:00:00", "document": "95", "payer": "Sarah Mcguire", "amount": 735} +{"id": "7e121e0e-5c17-4b85-af8d-0567ef56e029", "type": "bank_slip", "created_at": "2022-12-20T00:00:00", "document": "73", "payer": "Fe Bartkowiak", "amount": 6789} +{"id": "34b68a91-6f3a-4925-aa21-c3ec41e95c26", "type": "debit", "created_at": "2022-07-05T00:00:00", "document": "54", "payer": "Carmela Ho", "amount": 2222} +{"id": "19121a0e-4377-4c7d-a5ee-9aae614c4839", "type": "debit", "created_at": "2022-08-06T00:00:00", "document": "96", "payer": "Earl Morgan", "amount": 4821} +{"id": "cb9f66a6-296b-4322-9714-a89138c62d63", "type": "debit", "created_at": "2022-05-15T00:00:00", "document": "30", "payer": "Ronald Shurtleff", "amount": 8215} +{"id": "6a9a914d-76af-483e-b9d0-66abfa6b9e95", "type": "debit", "created_at": "2022-02-10T00:00:00", "document": "16", "payer": "Gary Kozak", "amount": 7592} +{"id": "98741d86-984c-4c98-8bdc-93190550775b", "type": "credit", "created_at": "2022-06-05T00:00:00", "document": "58", "payer": "Erin Rhoads", "amount": 7028} +{"id": "b8a990ba-fd60-4a1c-9d47-2ad7c7e0512f", "type": "bank_slip", "created_at": "2022-11-01T00:00:00", "document": "59", "payer": "Elizabeth Robinson", "amount": 1647} +{"id": "2fa75936-3d67-41d6-a751-1ccb190a42da", "type": "debit", "created_at": "2022-06-20T00:00:00", "document": "9", "payer": "Connie Randall", "amount": 9290} +{"id": "70ce7df9-0eca-47ba-9459-61358acc015f", "type": "credit", "created_at": "2022-07-18T00:00:00", "document": "47", "payer": "Dustin Diller", "amount": 6106} +{"id": "11c5f8c4-8017-456e-a26b-d13a83926737", "type": "credit", "created_at": "2022-02-22T00:00:00", "document": "44", "payer": "Kevin Parry", "amount": 4741} +{"id": "3d83d16e-9aca-44e6-a76e-d4280945ef3a", "type": "bank_slip", "created_at": "2022-05-09T00:00:00", "document": "4", "payer": "Marcia Griffin", "amount": 4202} +{"id": "0ef18ef6-f824-49a7-b807-9f9129262347", "type": "debit", "created_at": "2022-03-31T00:00:00", "document": "56", "payer": "Katherine Alexander", "amount": 6813} +{"id": "4fda02e5-c86a-4bc6-b40f-2c03dd6bfffd", "type": "bank_slip", "created_at": "2022-11-11T00:00:00", "document": "73", "payer": "Fe Bartkowiak", "amount": 79} +{"id": "ada71770-7f42-42e5-93f3-d84e7a883a6a", "type": "bank_slip", "created_at": "2022-05-20T00:00:00", "document": "13", "payer": "Janet Perry", "amount": 6661} +{"id": "7eb4f100-4135-4817-916c-3d3a95b964c8", "type": "credit", "created_at": "2022-08-08T00:00:00", "document": "74", "payer": "Norma Brumit", "amount": 8687} +{"id": "b93b07ca-1954-4347-970a-d39acc87228e", "type": "credit", "created_at": "2022-12-29T00:00:00", "document": "69", "payer": "Mark Evans", "amount": 9100} +{"id": "8c0d9b63-af23-4984-97b2-a99d6b6f75c8", "type": "bank_slip", "created_at": "2022-06-22T00:00:00", "document": "34", "payer": "Sheila Ellard", "amount": 1941} +{"id": "63582bd7-6e81-41c9-86be-74269d674e13", "type": "bank_slip", "created_at": "2022-09-19T00:00:00", "document": "54", "payer": "Carmela Ho", "amount": 1275} +{"id": "bcb77f1f-decd-4ef6-9ab9-8aa148aad238", "type": "bank_slip", "created_at": "2022-09-09T00:00:00", "document": "3", "payer": "Conrad Hardin", "amount": 9389} +{"id": "9dcb9da3-06da-41c4-a140-aa40136aac5a", "type": "credit", "created_at": "2022-02-13T00:00:00", "document": "79", "payer": "Steven Rapp", "amount": 4451} +{"id": "f6dfa95f-7841-4f84-bf8c-db2d69ded334", "type": "bank_slip", "created_at": "2022-03-16T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 2842} +{"id": "5e0297be-194d-444e-8fb0-7e7e06a161ed", "type": "bank_slip", "created_at": "2022-02-03T00:00:00", "document": "54", "payer": "Carmela Ho", "amount": 4792} +{"id": "6252ab0e-ffbe-47d1-aa06-f1104c646434", "type": "bank_slip", "created_at": "2022-03-07T00:00:00", "document": "64", "payer": "Elizabeth Bobadilla", "amount": 9102} +{"id": "079859e6-6d46-45d0-b6c0-fa753aafb90d", "type": "credit", "created_at": "2022-07-10T00:00:00", "document": "97", "payer": "Marc Greer", "amount": 2163} +{"id": "c2a91737-0dfe-4b2d-ac70-780f40f2a189", "type": "bank_slip", "created_at": "2022-04-13T00:00:00", "document": "8", "payer": "Nicky Jones", "amount": 3824} +{"id": "613a7609-01ab-4c13-8e25-3eeb42873cbb", "type": "credit", "created_at": "2022-04-18T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 4522} +{"id": "457d0d3d-0ae8-4bde-9da0-b5cebfc3504b", "type": "debit", "created_at": "2022-07-21T00:00:00", "document": "75", "payer": "Edie Callam", "amount": 4538} +{"id": "72d6d64a-dfc0-4fb8-86ce-80da1bc60892", "type": "debit", "created_at": "2022-09-14T00:00:00", "document": "79", "payer": "Steven Rapp", "amount": 5419} +{"id": "80ddd00c-562a-44b5-8b5e-0e8bd61342c6", "type": "credit", "created_at": "2022-10-29T00:00:00", "document": "43", "payer": "Gary Jensen", "amount": 2311} +{"id": "9ea31658-2942-492b-9c58-2ecc12d65228", "type": "bank_slip", "created_at": "2022-12-08T00:00:00", "document": "73", "payer": "Fe Bartkowiak", "amount": 816} +{"id": "388f1ef8-7d46-4d21-81f3-f6562dc327bf", "type": "bank_slip", "created_at": "2022-10-13T00:00:00", "document": "52", "payer": "Derek Corcoran", "amount": 6987} +{"id": "b01e19d9-522f-4e72-b5ce-27fa29fd3d20", "type": "credit", "created_at": "2022-07-08T00:00:00", "document": "41", "payer": "Tamera Boone", "amount": 2361} +{"id": "437f9247-65bd-4b0a-9d00-9646cf844e84", "type": "credit", "created_at": "2022-08-20T00:00:00", "document": "9", "payer": "Connie Randall", "amount": 750} +{"id": "d28c7489-cb4a-480b-9e46-e76dadd3e455", "type": "bank_slip", "created_at": "2022-01-27T00:00:00", "document": "71", "payer": "Florence Henderson", "amount": 4194} +{"id": "563d63ab-3303-444b-9498-42fc7651cc7f", "type": "debit", "created_at": "2022-03-13T00:00:00", "document": "12", "payer": "Susan Woodward", "amount": 4510} +{"id": "36a40ca1-b6dd-4626-8a2c-a1450a22ac2e", "type": "debit", "created_at": "2022-09-06T00:00:00", "document": "73", "payer": "Fe Bartkowiak", "amount": 9728} +{"id": "02c523c1-aca2-4095-bbe0-112e5df3684f", "type": "bank_slip", "created_at": "2022-09-26T00:00:00", "document": "35", "payer": "Maggie Auten", "amount": 3404} +{"id": "c0f1e648-2028-48ad-a005-3cb2c100783b", "type": "credit", "created_at": "2022-09-24T00:00:00", "document": "74", "payer": "Norma Brumit", "amount": 7789} +{"id": "41626e98-2638-4e3e-a1c9-37be5dbb4c19", "type": "credit", "created_at": "2022-08-08T00:00:00", "document": "60", "payer": "Rachel York", "amount": 7230} +{"id": "5087fb2f-8d9b-465e-9c33-cc406a601075", "type": "bank_slip", "created_at": "2022-08-05T00:00:00", "document": "86", "payer": "Robert Kraft", "amount": 5116} +{"id": "cb10a857-9bb1-4ab6-bca3-dd5f734cf535", "type": "credit", "created_at": "2022-07-12T00:00:00", "document": "4", "payer": "Marcia Griffin", "amount": 8537} +{"id": "bc76c74f-8f6a-4103-ab94-ecbcd65c97ab", "type": "bank_slip", "created_at": "2022-04-06T00:00:00", "document": "0", "payer": "Ruth Sheth", "amount": 8291} +{"id": "070d0ed7-9cee-4e75-938e-404bb80a9dcc", "type": "bank_slip", "created_at": "2022-02-16T00:00:00", "document": "26", "payer": "Robert Krupp", "amount": 9812} +{"id": "90cd0a2f-2dc9-4872-8052-6f5e0fd1e876", "type": "bank_slip", "created_at": "2022-06-15T00:00:00", "document": "26", "payer": "Robert Krupp", "amount": 5053} +{"id": "222f8c46-15bb-43aa-800d-6dc2a05aa4a4", "type": "bank_slip", "created_at": "2022-10-24T00:00:00", "document": "18", "payer": "Armida Kostrzewa", "amount": 8670} +{"id": "81d1a61a-4b80-4b79-878c-a4675480f52c", "type": "debit", "created_at": "2022-07-02T00:00:00", "document": "56", "payer": "Katherine Alexander", "amount": 781} +{"id": "9505fd83-2b83-412b-aa00-17bada1eb572", "type": "bank_slip", "created_at": "2022-11-13T00:00:00", "document": "13", "payer": "Janet Perry", "amount": 65} +{"id": "dd078cc4-4002-491a-8145-fdf2884348d0", "type": "bank_slip", "created_at": "2022-05-28T00:00:00", "document": "88", "payer": "Gabrielle Santoyo", "amount": 128} +{"id": "401d2f86-6cd4-4f0a-b775-9a9527cb9a51", "type": "debit", "created_at": "2022-12-18T00:00:00", "document": "83", "payer": "Filomena Suther", "amount": 691} +{"id": "3fd84e24-815b-42e7-98c1-607ddb61b375", "type": "bank_slip", "created_at": "2022-07-20T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 3101} +{"id": "72adbe0f-7109-431a-a863-a8e80187f760", "type": "credit", "created_at": "2022-03-05T00:00:00", "document": "33", "payer": "Charlotte Marczak", "amount": 3565} +{"id": "449068f7-e806-4bd7-8919-3d2c07ea76c1", "type": "debit", "created_at": "2022-11-03T00:00:00", "document": "65", "payer": "William Boxer", "amount": 9027} +{"id": "72063e36-ac6c-4fb3-a9bd-e2b7f281263f", "type": "debit", "created_at": "2022-09-24T00:00:00", "document": "32", "payer": "Barbara Harris", "amount": 6465} +{"id": "c3bbc3bb-d773-402b-954c-cebaddbbe8f0", "type": "debit", "created_at": "2022-10-07T00:00:00", "document": "17", "payer": "Janice Coughlin", "amount": 1572} +{"id": "79f4a37a-55e7-4887-a621-0f34bc559c52", "type": "bank_slip", "created_at": "2022-02-22T00:00:00", "document": "69", "payer": "Mark Evans", "amount": 1326} +{"id": "cfd9340a-d820-4acc-bffa-c981b1939550", "type": "credit", "created_at": "2022-01-18T00:00:00", "document": "53", "payer": "Louise Witherspoon", "amount": 1487} +{"id": "f03afd3c-4b44-4f03-852d-e2609b89f586", "type": "debit", "created_at": "2022-12-07T00:00:00", "document": "60", "payer": "Rachel York", "amount": 6945} +{"id": "430b590d-f93c-4c5b-972c-c06f5f78622d", "type": "debit", "created_at": "2022-05-26T00:00:00", "document": "7", "payer": "Maria Bonney", "amount": 8406} +{"id": "c172de72-e712-44d7-9595-59204d10ccbc", "type": "debit", "created_at": "2022-11-12T00:00:00", "document": "7", "payer": "Maria Bonney", "amount": 5313} +{"id": "02db4ec5-ab83-4ca7-a60a-dca48d782fa3", "type": "bank_slip", "created_at": "2022-01-30T00:00:00", "document": "87", "payer": "Emily Cockerill", "amount": 8662} +{"id": "0feb1d52-0e1b-4fa6-9c42-99a58224473d", "type": "bank_slip", "created_at": "2022-02-18T00:00:00", "document": "27", "payer": "Devin Felt", "amount": 9956} +{"id": "f6f8ea73-442a-4551-b958-cb75fcd83ef5", "type": "bank_slip", "created_at": "2022-01-02T00:00:00", "document": "47", "payer": "Dustin Diller", "amount": 5694} +{"id": "3d7d28d0-b1d3-4a60-8042-808fe71133c9", "type": "credit", "created_at": "2022-03-20T00:00:00", "document": "73", "payer": "Fe Bartkowiak", "amount": 9905} +{"id": "776d87d3-fc3b-42ba-ac74-572798608535", "type": "debit", "created_at": "2022-08-16T00:00:00", "document": "21", "payer": "Richard Duckett", "amount": 9789} +{"id": "fcf569a2-205b-46f5-b8dc-49953d0eea6c", "type": "bank_slip", "created_at": "2022-04-01T00:00:00", "document": "87", "payer": "Emily Cockerill", "amount": 6698} +{"id": "daf72ab9-1d00-47b9-8d68-81dc0efa611c", "type": "bank_slip", "created_at": "2022-05-18T00:00:00", "document": "99", "payer": "Mark Seidel", "amount": 3616} +{"id": "03176959-14a8-43c6-b194-1048b7e6d394", "type": "credit", "created_at": "2022-02-10T00:00:00", "document": "2", "payer": "Ella Tatum", "amount": 8395} +{"id": "c030b899-67da-45f8-8f63-4815f5d93cd1", "type": "debit", "created_at": "2022-07-21T00:00:00", "document": "19", "payer": "Patrick Monson", "amount": 7327} +{"id": "0cc2cf12-43d0-4672-8c58-4d33ade4bed2", "type": "debit", "created_at": "2022-03-27T00:00:00", "document": "81", "payer": "Steven Delosantos", "amount": 1621} +{"id": "f19ad312-8f2f-41b7-b454-01503426094a", "type": "debit", "created_at": "2022-10-10T00:00:00", "document": "71", "payer": "Florence Henderson", "amount": 5475} +{"id": "12e4662e-0dfb-4347-a14c-9df153faddb6", "type": "debit", "created_at": "2022-09-05T00:00:00", "document": "21", "payer": "Richard Duckett", "amount": 7792} +{"id": "62b783ba-e6aa-45bd-8e85-8204364a1c2e", "type": "credit", "created_at": "2022-07-04T00:00:00", "document": "80", "payer": "Joyce Wimberly", "amount": 80} +{"id": "661a7644-ce14-49d4-b267-b2f72b0c9e8d", "type": "bank_slip", "created_at": "2022-09-21T00:00:00", "document": "29", "payer": "Timothy Short", "amount": 2140} +{"id": "745feb36-cad3-47a5-b38b-c62324dedbc2", "type": "credit", "created_at": "2022-10-28T00:00:00", "document": "18", "payer": "Armida Kostrzewa", "amount": 9459} \ No newline at end of file diff --git a/ccloud/custom-connector-connect-iceberg-sink/docker-compose.yml b/ccloud/custom-connector-connect-iceberg-sink/docker-compose.yml new file mode 100644 index 0000000000..a822d625d6 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/docker-compose.yml @@ -0,0 +1,106 @@ +--- +services: + # based on https://github.com/Wuerike/kafka-iceberg-streaming/tree/main + minio: + image: minio/minio + hostname: minio + container_name: minio + environment: + - MINIO_ROOT_USER=minioadmin + - MINIO_ROOT_PASSWORD=minioadmin + - MINIO_DOMAIN=minio + networks: + default: + aliases: + - warehouse.minio + ports: + - 9001:9001 + - 9000:9000 + command: ["server", "/data", "--console-address", ":9001"] + + aws: + image: amazon/aws-cli + container_name: aws-cli + command: | + -c "sleep 2 && \ + aws --endpoint-url http://minio:9000 s3 mb s3://warehouse --region eu-west-1 || exit 0" + entrypoint: [/bin/bash] + environment: + AWS_ACCESS_KEY_ID: "minioadmin" + AWS_SECRET_ACCESS_KEY: "minioadmin" + depends_on: + - minio + + spark-iceberg: + image: tabulario/spark-iceberg + hostname: spark-iceberg + container_name: spark-iceberg + build: ../../ccloud/custom-connector-connect-iceberg-sink/spark/ + depends_on: + - rest + - minio + environment: + AWS_ACCESS_KEY_ID: minioadmin + AWS_SECRET_ACCESS_KEY: minioadmin + AWS_REGION: eu-west-1 + SPARK_DEFAULTS: | + spark.sql.extensions org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions + spark.sql.catalog.iceberg org.apache.iceberg.spark.SparkCatalog + spark.sql.catalog.iceberg.catalog-impl org.apache.iceberg.rest.RESTCatalog + spark.sql.catalog.iceberg.uri http://rest:8181 + spark.sql.catalog.iceberg.io-impl org.apache.iceberg.aws.s3.S3FileIO + spark.sql.catalog.iceberg.warehouse s3://warehouse/wh/ + spark.sql.catalog.iceberg.s3.endpoint http://minio:9000 + spark.sql.catalog.iceberg.s3.path-style-access true + spark.sql.defaultCatalog iceberg + spark.sql.catalogImplementation in-memory + spark.eventLog.enabled true + spark.eventLog.dir /home/iceberg/spark-events + spark.history.fs.logDirectory /home/iceberg/spark-events + spark.jars.packages org.apache.hadoop:hadoop-aws:3.2.0 + ports: + - 8888:8888 + # - 8080:8080 + # - 10000:10000 + # - 10001:10001 + volumes: + - ../../ccloud/custom-connector-connect-iceberg-sink/spark:/home/iceberg/scripts + - ../../ccloud/custom-connector-connect-iceberg-sink/notebooks:/home/iceberg/notebooks/notebooks + command: ["echo \"$$SPARK_DEFAULTS\" > /opt/spark/conf/spark-defaults.conf && spark-submit /home/iceberg/scripts/create_table.py && notebook"] + + rest: + image: tabulario/iceberg-rest + hostname: rest + container_name: rest + ports: + - 8181:8181 + environment: + - AWS_ACCESS_KEY_ID=minioadmin + - AWS_SECRET_ACCESS_KEY=minioadmin + - AWS_REGION=eu-west-1 + - CATALOG_WAREHOUSE=s3://warehouse/ + - CATALOG_IO__IMPL=org.apache.iceberg.aws.s3.S3FileIO + - CATALOG_S3_ENDPOINT=http://minio:9000 + - CATALOG_S3_PATH__STYLE__ACCESS=True + + # https://ngrok.com/docs/using-ngrok-with/docker/ + ngrok: + image: ngrok/ngrok:latest + hostname: ngrok + container_name: ngrok + ports: + - 4040:4040 + restart: unless-stopped + links: + - minio + - rest + command: + - "start" + - "--all" + - "--log=stdout" + - "--config" + - "/etc/ngrok.yml" + volumes: + - ../../ccloud/custom-connector-connect-iceberg-sink/ngrok.yml:/etc/ngrok.yml + environment: + NGROK_AUTHTOKEN: $NGROK_AUTH_TOKEN diff --git a/ccloud/custom-connector-connect-iceberg-sink/ngrok.yml b/ccloud/custom-connector-connect-iceberg-sink/ngrok.yml new file mode 100644 index 0000000000..0ed8fdded3 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/ngrok.yml @@ -0,0 +1,8 @@ +version: 2 +tunnels: + minio: + addr: minio:9000 + proto: tcp + rest: + addr: rest:8181 + proto: tcp \ No newline at end of file diff --git a/ccloud/custom-connector-connect-iceberg-sink/notebooks/.ipynb_checkpoints/Untitled-checkpoint.ipynb b/ccloud/custom-connector-connect-iceberg-sink/notebooks/.ipynb_checkpoints/Untitled-checkpoint.ipynb new file mode 100644 index 0000000000..363fcab7ed --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/notebooks/.ipynb_checkpoints/Untitled-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ccloud/custom-connector-connect-iceberg-sink/notebooks/.ipynb_checkpoints/iceberg-checkpoint.ipynb b/ccloud/custom-connector-connect-iceberg-sink/notebooks/.ipynb_checkpoints/iceberg-checkpoint.ipynb new file mode 100644 index 0000000000..15aa20543b --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/notebooks/.ipynb_checkpoints/iceberg-checkpoint.ipynb @@ -0,0 +1,103 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "29f8d24e-e4bf-484d-afd4-cb82ff6cd50d", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SHOW DATABASES" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "70349765-e5f1-43a5-a141-cc2d54c69a58", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SHOW TABLES FROM orders" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fabaed9c-9049-4996-9d26-b20f66303911", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SHOW TBLPROPERTIES orders.payments" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6317d9c6-140e-4a63-890e-2173fbb9503e", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT COUNT(*)\n", + "FROM orders.payments" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2a1ff132-dc65-4943-a9be-416ba5a13c26", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT *\n", + "FROM orders.payments\n", + "LIMIT 10" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a2688a95-594c-45ad-9d49-70a1bcd59a1b", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT * \n", + "FROM orders.payments.partitions\n", + "ORDER BY record_count DESC\n", + "LIMIT 10" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.17" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ccloud/custom-connector-connect-iceberg-sink/notebooks/Untitled.ipynb b/ccloud/custom-connector-connect-iceberg-sink/notebooks/Untitled.ipynb new file mode 100644 index 0000000000..d785557639 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/notebooks/Untitled.ipynb @@ -0,0 +1,33 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "e5b4f2cb-d4fe-4376-a4e9-d6683887b1b7", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.20" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ccloud/custom-connector-connect-iceberg-sink/notebooks/iceberg.ipynb b/ccloud/custom-connector-connect-iceberg-sink/notebooks/iceberg.ipynb new file mode 100644 index 0000000000..152a1d29f8 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/notebooks/iceberg.ipynb @@ -0,0 +1,249 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "29f8d24e-e4bf-484d-afd4-cb82ff6cd50d", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "24/10/16 10:11:21 WARN SparkSession: Using an existing Spark session; only runtime SQL configurations will take effect.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namespace
orders
" + ], + "text/plain": [ + "+-----------+\n", + "| namespace |\n", + "+-----------+\n", + "| orders |\n", + "+-----------+" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "\n", + "SHOW DATABASES" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "70349765-e5f1-43a5-a141-cc2d54c69a58", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SHOW TABLES FROM orders" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fabaed9c-9049-4996-9d26-b20f66303911", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SHOW TBLPROPERTIES orders.payments" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "6317d9c6-140e-4a63-890e-2173fbb9503e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
count(1)
0
" + ], + "text/plain": [ + "+----------+\n", + "| count(1) |\n", + "+----------+\n", + "| 0 |\n", + "+----------+" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "\n", + "SELECT COUNT(*)\n", + "FROM orders.payments" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "2a1ff132-dc65-4943-a9be-416ba5a13c26", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idtypecreated_atdocumentpayeramount
" + ], + "text/plain": [ + "+----+------+------------+----------+-------+--------+\n", + "| id | type | created_at | document | payer | amount |\n", + "+----+------+------------+----------+-------+--------+\n", + "+----+------+------------+----------+-------+--------+" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "\n", + "SELECT *\n", + "FROM orders.payments\n", + "LIMIT 10" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a2688a95-594c-45ad-9d49-70a1bcd59a1b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
partitionspec_idrecord_countfile_counttotal_data_file_size_in_bytesposition_delete_record_countposition_delete_file_countequality_delete_record_countequality_delete_file_countlast_updated_atlast_updated_snapshot_id
" + ], + "text/plain": [ + "+-----------+---------+--------------+------------+-------------------------------+------------------------------+----------------------------+------------------------------+----------------------------+-----------------+--------------------------+\n", + "| partition | spec_id | record_count | file_count | total_data_file_size_in_bytes | position_delete_record_count | position_delete_file_count | equality_delete_record_count | equality_delete_file_count | last_updated_at | last_updated_snapshot_id |\n", + "+-----------+---------+--------------+------------+-------------------------------+------------------------------+----------------------------+------------------------------+----------------------------+-----------------+--------------------------+\n", + "+-----------+---------+--------------+------------+-------------------------------+------------------------------+----------------------------+------------------------------+----------------------------+-----------------+--------------------------+" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "\n", + "SELECT * \n", + "FROM orders.payments.partitions\n", + "ORDER BY record_count DESC\n", + "LIMIT 10" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c576e9ab-b014-44f8-ba79-c5f16b4b719b", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15bbf09b-c29e-4911-b82e-839e9f854756", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.20" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/.pyiceberg.yaml b/ccloud/custom-connector-connect-iceberg-sink/spark/.pyiceberg.yaml new file mode 100644 index 0000000000..7444ab0999 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/.pyiceberg.yaml @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +catalog: + default: + uri: http://rest:8181 + s3.endpoint: http://minio:9000 + s3.access-key-id: admin + s3.secret-access-key: password diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/Dockerfile b/ccloud/custom-connector-connect-iceberg-sink/spark/Dockerfile new file mode 100644 index 0000000000..bd8760a55b --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/Dockerfile @@ -0,0 +1,125 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# syntax=docker/dockerfile:1 +FROM python:3.9-bullseye + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + sudo \ + curl \ + vim \ + unzip \ + openjdk-11-jdk \ + build-essential \ + software-properties-common \ + ssh && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Install Jupyter and other python deps +COPY requirements.txt . +RUN pip3 install -r requirements.txt + +# Add scala kernel via spylon-kernel +RUN python3 -m spylon_kernel install + +# Download and install IJava jupyter kernel +RUN curl https://github.com/SpencerPark/IJava/releases/download/v1.3.0/ijava-1.3.0.zip -Lo ijava-1.3.0.zip \ + && unzip ijava-1.3.0.zip \ + && python3 install.py --sys-prefix \ + && rm ijava-1.3.0.zip + +# Optional env variables +ENV SPARK_HOME=${SPARK_HOME:-"/opt/spark"} +ENV PYTHONPATH=$SPARK_HOME/python:$SPARK_HOME/python/lib/py4j-0.10.9.7-src.zip:$PYTHONPATH + +WORKDIR ${SPARK_HOME} + +ENV SPARK_VERSION=3.5.3 +ENV SPARK_MAJOR_VERSION=3.5 +ENV ICEBERG_VERSION=1.5.0 + +# Download spark +RUN mkdir -p ${SPARK_HOME} \ + && curl https://dlcdn.apache.org/spark/spark-${SPARK_VERSION}/spark-${SPARK_VERSION}-bin-hadoop3.tgz -o spark-${SPARK_VERSION}-bin-hadoop3.tgz \ + && tar xvzf spark-${SPARK_VERSION}-bin-hadoop3.tgz --directory /opt/spark --strip-components 1 \ + && rm -rf spark-${SPARK_VERSION}-bin-hadoop3.tgz + +# Download iceberg spark runtime +RUN curl https://repo1.maven.org/maven2/org/apache/iceberg/iceberg-spark-runtime-${SPARK_MAJOR_VERSION}_2.12/${ICEBERG_VERSION}/iceberg-spark-runtime-${SPARK_MAJOR_VERSION}_2.12-${ICEBERG_VERSION}.jar -Lo /opt/spark/jars/iceberg-spark-runtime-${SPARK_MAJOR_VERSION}_2.12-${ICEBERG_VERSION}.jar + +# Download AWS bundle +RUN curl -s https://repo1.maven.org/maven2/org/apache/iceberg/iceberg-aws-bundle/${ICEBERG_VERSION}/iceberg-aws-bundle-${ICEBERG_VERSION}.jar -Lo /opt/spark/jars/iceberg-aws-bundle-${ICEBERG_VERSION}.jar + +# Install AWS CLI +RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" \ + && unzip awscliv2.zip \ + && sudo ./aws/install \ + && rm awscliv2.zip \ + && rm -rf aws/ + +# Add iceberg spark runtime jar to IJava classpath +ENV IJAVA_CLASSPATH=/opt/spark/jars/* + +RUN mkdir -p /home/iceberg/data \ + && curl https://data.cityofnewyork.us/resource/tg4x-b46p.json > /home/iceberg/data/nyc_film_permits.json \ + && curl https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2022-04.parquet -o /home/iceberg/data/yellow_tripdata_2022-04.parquet \ + && curl https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2022-03.parquet -o /home/iceberg/data/yellow_tripdata_2022-03.parquet \ + && curl https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2022-02.parquet -o /home/iceberg/data/yellow_tripdata_2022-02.parquet \ + && curl https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2022-01.parquet -o /home/iceberg/data/yellow_tripdata_2022-01.parquet \ + && curl https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-12.parquet -o /home/iceberg/data/yellow_tripdata_2021-12.parquet \ + && curl https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-11.parquet -o /home/iceberg/data/yellow_tripdata_2021-11.parquet \ + && curl https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-10.parquet -o /home/iceberg/data/yellow_tripdata_2021-10.parquet \ + && curl https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-09.parquet -o /home/iceberg/data/yellow_tripdata_2021-09.parquet \ + && curl https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-08.parquet -o /home/iceberg/data/yellow_tripdata_2021-08.parquet \ + && curl https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-07.parquet -o /home/iceberg/data/yellow_tripdata_2021-07.parquet \ + && curl https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-06.parquet -o /home/iceberg/data/yellow_tripdata_2021-06.parquet \ + && curl https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-05.parquet -o /home/iceberg/data/yellow_tripdata_2021-05.parquet \ + && curl https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-04.parquet -o /home/iceberg/data/yellow_tripdata_2021-04.parquet + +RUN mkdir -p /home/iceberg/localwarehouse /home/iceberg/notebooks /home/iceberg/warehouse /home/iceberg/spark-events /home/iceberg +COPY notebooks/ /home/iceberg/notebooks + +# Add a notebook command +RUN echo '#! /bin/sh' >> /bin/notebook \ + && echo 'export PYSPARK_DRIVER_PYTHON=jupyter-notebook' >> /bin/notebook \ + && echo "export PYSPARK_DRIVER_PYTHON_OPTS=\"--notebook-dir=/home/iceberg/notebooks --ip='*' --NotebookApp.token='' --NotebookApp.password='' --port=8888 --no-browser --allow-root\"" >> /bin/notebook \ + && echo "pyspark" >> /bin/notebook \ + && chmod u+x /bin/notebook + +# Add a pyspark-notebook command (alias for notebook command for backwards-compatibility) +RUN echo '#! /bin/sh' >> /bin/pyspark-notebook \ + && echo 'export PYSPARK_DRIVER_PYTHON=jupyter-notebook' >> /bin/pyspark-notebook \ + && echo "export PYSPARK_DRIVER_PYTHON_OPTS=\"--notebook-dir=/home/iceberg/notebooks --ip='*' --NotebookApp.token='' --NotebookApp.password='' --port=8888 --no-browser --allow-root\"" >> /bin/pyspark-notebook \ + && echo "pyspark" >> /bin/pyspark-notebook \ + && chmod u+x /bin/pyspark-notebook + +RUN mkdir -p /root/.ipython/profile_default/startup +COPY ipython/startup/00-prettytables.py /root/.ipython/profile_default/startup +COPY ipython/startup/README /root/.ipython/profile_default/startup + +COPY spark-defaults.conf /opt/spark/conf +ENV PATH="/opt/spark/sbin:/opt/spark/bin:${PATH}" + +RUN chmod u+x /opt/spark/sbin/* && \ + chmod u+x /opt/spark/bin/* + +COPY .pyiceberg.yaml /root/.pyiceberg.yaml + +COPY entrypoint.sh . + +ENTRYPOINT ["./entrypoint.sh"] +CMD ["notebook"] diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/create_table.py b/ccloud/custom-connector-connect-iceberg-sink/spark/create_table.py new file mode 100644 index 0000000000..92525744d0 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/create_table.py @@ -0,0 +1,20 @@ +from pyspark.sql import SparkSession + +spark = SparkSession.builder.appName("").getOrCreate() + +print("creating database") +spark.sql('CREATE DATABASE IF NOT EXISTS orders') + +print("creating table") +spark.sql(''' + CREATE TABLE IF NOT EXISTS orders.payments ( + id STRING, + type STRING, + created_at TIMESTAMP, + document STRING, + payer STRING, + amount INT + ) + USING iceberg + PARTITIONED BY (document) +''') diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/entrypoint.sh b/ccloud/custom-connector-connect-iceberg-sink/spark/entrypoint.sh new file mode 100755 index 0000000000..2738b59bac --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/entrypoint.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +start-master.sh -p 7077 +start-worker.sh spark://spark-iceberg:7077 +start-history-server.sh +start-thriftserver.sh --driver-java-options "-Dderby.system.home=/tmp/derby" + +# Entrypoint, for example notebook, pyspark or spark-sql +if [[ $# -gt 0 ]] ; then + eval "$1" +fi diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/ipython/startup/00-prettytables.py b/ccloud/custom-connector-connect-iceberg-sink/spark/ipython/startup/00-prettytables.py new file mode 100644 index 0000000000..868f7e5ae0 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/ipython/startup/00-prettytables.py @@ -0,0 +1,81 @@ + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from prettytable import PrettyTable +from IPython.core.magic import register_line_cell_magic + +class DFTable(PrettyTable): + def __repr__(self): + return self.get_string() + + def _repr_html_(self): + return self.get_html_string() + +def _row_as_table(df): + cols = df.columns + + t = DFTable() + t.field_names = ["Column", "Value"] + t.align = "r" + row = df.limit(1).collect()[0].asDict() + for col in cols: + t.add_row([ col, row[col] ]) + + return t + +def _to_table(df, num_rows=100): + cols = df.columns + + t = DFTable() + t.field_names = cols + t.align = "r" + for row in df.limit(num_rows).collect(): + d = row.asDict() + t.add_row([ d[col] for col in cols ]) + + return t + +import re +import sys +from argparse import ArgumentParser +parser = ArgumentParser() +parser.add_argument("--limit", help="Number of lines to return", type=int, default=100) +parser.add_argument("--var", help="Variable name to hold the dataframe", type=str) + +@register_line_cell_magic +def sql(line, cell=None): + """Spark SQL magic + """ + from pyspark.sql import SparkSession + spark = SparkSession.builder.appName("Jupyter").getOrCreate() + if cell is None: + return _to_table(spark.sql(line)) + elif line: + df = spark.sql(cell) + + (args, others) = parser.parse_known_args([ arg for arg in re.split("\s+", line) if arg ]) + + if args.var: + setattr(sys.modules[__name__], args.var, df) + + if args.limit == 1: + return _row_as_table(df) + else: + return _to_table(df, num_rows=args.limit) + else: + return _to_table(spark.sql(cell)) diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/ipython/startup/README b/ccloud/custom-connector-connect-iceberg-sink/spark/ipython/startup/README new file mode 100644 index 0000000000..61d4700042 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/ipython/startup/README @@ -0,0 +1,11 @@ +This is the IPython startup directory + +.py and .ipy files in this directory will be run *prior* to any code or files specified +via the exec_lines or exec_files configurables whenever you load this profile. + +Files will be run in lexicographical order, so you can control the execution order of files +with a prefix, e.g.:: + + 00-first.py + 50-middle.py + 99-last.ipy diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - An Introduction to the Iceberg Java API.ipynb b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - An Introduction to the Iceberg Java API.ipynb new file mode 100644 index 0000000000..20af42b17b --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - An Introduction to the Iceberg Java API.ipynb @@ -0,0 +1,469 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "16f6bb49", + "metadata": {}, + "source": [ + "![iceberg-logo](https://www.apache.org/logos/res/iceberg/iceberg.png)" + ] + }, + { + "cell_type": "markdown", + "id": "c82657e9", + "metadata": {}, + "source": [ + "# An Introduction to the Iceberg Java API" + ] + }, + { + "cell_type": "markdown", + "id": "3ee90ad2", + "metadata": {}, + "source": [ + "## [Part 1 - Loading a Catalog and Creating a Table](https://tabular.io/blog/java-api-part-1/)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "72e68c62", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.catalog.Catalog;\n", + "import org.apache.hadoop.conf.Configuration;\n", + "import org.apache.iceberg.CatalogProperties;\n", + "import org.apache.iceberg.rest.RESTCatalog;\n", + "import org.apache.iceberg.aws.s3.S3FileIOProperties;\n", + "\n", + "Map properties = new HashMap<>();\n", + "\n", + "properties.put(CatalogProperties.CATALOG_IMPL, \"org.apache.iceberg.rest.RESTCatalog\");\n", + "properties.put(CatalogProperties.URI, \"http://rest:8181\");\n", + "properties.put(CatalogProperties.WAREHOUSE_LOCATION, \"s3a://warehouse/wh\");\n", + "properties.put(CatalogProperties.FILE_IO_IMPL, \"org.apache.iceberg.aws.s3.S3FileIO\");\n", + "properties.put(S3FileIOProperties.ENDPOINT, \"http://minio:9000\");\n", + "\n", + "RESTCatalog catalog = new RESTCatalog();\n", + "Configuration conf = new Configuration();\n", + "catalog.setConf(conf);\n", + "catalog.initialize(\"demo\", properties);\n", + "catalog.name();" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4be615e7", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.Schema;\n", + "import org.apache.iceberg.types.Types;\n", + "\n", + "Schema schema = new Schema(\n", + " Types.NestedField.required(1, \"level\", Types.StringType.get()),\n", + " Types.NestedField.required(2, \"event_time\", Types.TimestampType.withZone()),\n", + " Types.NestedField.required(3, \"message\", Types.StringType.get()),\n", + " Types.NestedField.optional(4, \"call_stack\", Types.ListType.ofRequired(5, Types.StringType.get()))\n", + " );\n", + "schema" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b7299d16", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.PartitionSpec;\n", + "\n", + "PartitionSpec spec = PartitionSpec.builderFor(schema)\n", + " .hour(\"event_time\")\n", + " .identity(\"level\")\n", + " .build();\n", + "spec" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4d900c97", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.catalog.TableIdentifier;\n", + "import org.apache.iceberg.catalog.Namespace;\n", + "\n", + "Namespace nyc = Namespace.of(\"nyc\");\n", + "TableIdentifier name = TableIdentifier.of(nyc, \"logs\");\n", + "name" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8a4d8a6e", + "metadata": {}, + "outputs": [], + "source": [ + "catalog.createTable(name, schema, spec)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7d8c46df", + "metadata": {}, + "outputs": [], + "source": [ + "catalog.dropTable(name)" + ] + }, + { + "cell_type": "markdown", + "id": "fe62e0a9", + "metadata": {}, + "source": [ + "## [Part 2 - Table Scans](https://tabular.io/blog/java-api-part-2/)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c1e7aa7a", + "metadata": {}, + "outputs": [], + "source": [ + "catalog.createTable(name, schema, spec)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "78c95e06", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.spark.sql.SparkSession;\n", + "\n", + "SparkSession spark = SparkSession\n", + " .builder()\n", + " .master(\"local[*]\")\n", + " .appName(\"Java API Demo\")\n", + " .config(\"spark.sql.extensions\", \"org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions\")\n", + " .config(\"spark.sql.catalog.demo\", \"org.apache.iceberg.spark.SparkCatalog\")\n", + " .config(\"spark.sql.catalog.demo.catalog-impl\", \"org.apache.iceberg.rest.RESTCatalog\")\n", + " .config(\"spark.sql.catalog.demo.uri\", \"http://rest:8181\")\n", + " .config(\"spark.sql.catalog.demo.io-impl\", \"org.apache.iceberg.aws.s3.S3FileIO\")\n", + " .config(\"spark.sql.catalog.demo.s3.endpoint\", \"http://minio:9000\")\n", + " .config(\"spark.sql.defaultCatalog\", \"demo\")\n", + " .config(\"spark.eventLog.enabled\", \"true\")\n", + " .config(\"spark.eventLog.dir\", \"/home/iceberg/spark-events\")\n", + " .config(\"spark.history.fs.logDirectory\", \"/home/iceberg/spark-events\")\n", + " .getOrCreate();\n", + "\n", + "spark.sparkContext().setLogLevel(\"ERROR\");" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0b17f820", + "metadata": {}, + "outputs": [], + "source": [ + "String query = \"INSERT INTO demo.nyc.logs \"\n", + " + \"VALUES \"\n", + " + \"('info', timestamp 'today', 'Just letting you know!', array('stack trace line 1', 'stack trace line 2', 'stack trace line 3')), \"\n", + " + \"('warning', timestamp 'today', 'You probably should not do this!', array('stack trace line 1', 'stack trace line 2', 'stack trace line 3')), \"\n", + " + \"('error', timestamp 'today', 'This was a fatal application error!', array('stack trace line 1', 'stack trace line 2', 'stack trace line 3'))\";\n", + "\n", + "spark.sql(query).show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15ca1822", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.catalog.Catalog;\n", + "import org.apache.hadoop.conf.Configuration;\n", + "import org.apache.iceberg.CatalogProperties;\n", + "import org.apache.iceberg.rest.RESTCatalog;\n", + "\n", + "Map properties = new HashMap<>();\n", + "\n", + "properties.put(CatalogProperties.CATALOG_IMPL, \"org.apache.iceberg.rest.RESTCatalog\");\n", + "properties.put(CatalogProperties.URI, \"http://rest:8181\");\n", + "properties.put(CatalogProperties.WAREHOUSE_LOCATION, \"s3a://warehouse/wh/\");\n", + "properties.put(CatalogProperties.FILE_IO_IMPL, \"org.apache.iceberg.aws.s3.S3FileIO\");\n", + "properties.put(S3FileIOProperties.ENDPOINT, \"http://minio:9000\");\n", + "\n", + "RESTCatalog catalog = new RESTCatalog();\n", + "Configuration conf = new Configuration();\n", + "catalog.setConf(conf);\n", + "catalog.initialize(\"demo\", properties);" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3a5cf423", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.Table;\n", + "import org.apache.iceberg.TableScan;\n", + "import org.apache.iceberg.catalog.Namespace;\n", + "import org.apache.iceberg.catalog.TableIdentifier;\n", + "\n", + "Namespace nyc = Namespace.of(\"nyc\");\n", + "TableIdentifier name = TableIdentifier.of(nyc, \"logs\");\n", + "Table table = catalog.loadTable(name);" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e472d6a1", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.io.CloseableIterable;\n", + "import org.apache.iceberg.data.Record;\n", + "import org.apache.iceberg.data.IcebergGenerics;\n", + "\n", + "CloseableIterable result = IcebergGenerics.read(table).build();" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0d32f41c", + "metadata": {}, + "outputs": [], + "source": [ + "for (Record r: result) {\n", + " System.out.println(r);\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7dffc238", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.expressions.Expressions;\n", + "\n", + "CloseableIterable result = IcebergGenerics.read(table)\n", + " .where(Expressions.equal(\"level\", \"error\"))\n", + " .build();" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ec2b0431", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.CombinedScanTask;\n", + "import org.apache.iceberg.TableScan;\n", + "\n", + "TableScan scan = table.newScan();" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "09d13c6b", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.expressions.Expressions;\n", + "\n", + "TableScan filteredScan = scan.filter(Expressions.equal(\"level\", \"info\")).select(\"message\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1857c10f", + "metadata": {}, + "outputs": [], + "source": [ + "Iterable result = filteredScan.planTasks();" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea206ec7", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.DataFile;\n", + "\n", + "CombinedScanTask task = result.iterator().next();\n", + "DataFile dataFile = task.files().iterator().next().file();\n", + "System.out.println(dataFile);" + ] + }, + { + "cell_type": "markdown", + "id": "41e9e10f", + "metadata": {}, + "source": [ + "## [Part 3 - Table Scans](https://tabular.io/blog/java-api-part-3/)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "81033412", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.Schema;\n", + "import org.apache.iceberg.types.Types;\n", + "import org.apache.iceberg.catalog.Namespace;\n", + "import org.apache.iceberg.catalog.TableIdentifier;\n", + "import org.apache.iceberg.PartitionSpec;\n", + "\n", + "Schema schema = new Schema(\n", + " Types.NestedField.optional(1, \"event_id\", Types.StringType.get()),\n", + " Types.NestedField.optional(2, \"username\", Types.StringType.get()),\n", + " Types.NestedField.optional(3, \"userid\", Types.IntegerType.get()),\n", + " Types.NestedField.optional(4, \"api_version\", Types.StringType.get()),\n", + " Types.NestedField.optional(5, \"command\", Types.StringType.get())\n", + " );\n", + "\n", + "Namespace webapp = Namespace.of(\"webapp\");\n", + "TableIdentifier name = TableIdentifier.of(webapp, \"user_events\");\n", + "catalog.createTable(name, schema, PartitionSpec.unpartitioned());" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12c45c6b", + "metadata": {}, + "outputs": [], + "source": [ + "import java.util.UUID;\n", + "import com.google.common.collect.ImmutableList;\n", + "import com.google.common.collect.ImmutableMap;\n", + "import org.apache.iceberg.data.GenericRecord;\n", + "\n", + "GenericRecord record = GenericRecord.create(schema);\n", + "ImmutableList.Builder builder = ImmutableList.builder();\n", + "builder.add(record.copy(ImmutableMap.of(\"event_id\", UUID.randomUUID().toString(), \"username\", \"Bruce\", \"userid\", 1, \"api_version\", \"1.0\", \"command\", \"grapple\")));\n", + "builder.add(record.copy(ImmutableMap.of(\"event_id\", UUID.randomUUID().toString(), \"username\", \"Wayne\", \"userid\", 1, \"api_version\", \"1.0\", \"command\", \"glide\")));\n", + "builder.add(record.copy(ImmutableMap.of(\"event_id\", UUID.randomUUID().toString(), \"username\", \"Clark\", \"userid\", 1, \"api_version\", \"2.0\", \"command\", \"fly\")));\n", + "builder.add(record.copy(ImmutableMap.of(\"event_id\", UUID.randomUUID().toString(), \"username\", \"Kent\", \"userid\", 1, \"api_version\", \"1.0\", \"command\", \"land\")));\n", + "ImmutableList records = builder.build();" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "83bc5319", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.Files;\n", + "import org.apache.iceberg.io.DataWriter;\n", + "import org.apache.iceberg.io.OutputFile;\n", + "import org.apache.iceberg.parquet.Parquet;\n", + "import org.apache.iceberg.data.parquet.GenericParquetWriter;\n", + "\n", + "String filepath = table.location() + \"/\" + UUID.randomUUID().toString();\n", + "OutputFile file = table.io().newOutputFile(filepath);\n", + "DataWriter dataWriter =\n", + " Parquet.writeData(file)\n", + " .schema(schema)\n", + " .createWriterFunc(GenericParquetWriter::buildWriter)\n", + " .overwrite()\n", + " .withSpec(PartitionSpec.unpartitioned())\n", + " .build();\n", + "try {\n", + " for (GenericRecord record : builder.build()) {\n", + " dataWriter.write(record);\n", + " }\n", + "} finally {\n", + " dataWriter.close();\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "469e6af4", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.DataFile;\n", + "\n", + "DataFile dataFile = dataWriter.toDataFile();" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "142b6ed1", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.catalog.Namespace;\n", + "import org.apache.iceberg.catalog.TableIdentifier;\n", + "import org.apache.iceberg.Table;\n", + "\n", + "Namespace webapp = Namespace.of(\"webapp\");\n", + "TableIdentifier name = TableIdentifier.of(webapp, \"user_events\");\n", + "Table tbl = catalog.loadTable(name);\n", + "tbl.newAppend().appendFile(dataFile).commit()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c61e9e79", + "metadata": {}, + "outputs": [], + "source": [ + "import org.apache.iceberg.io.CloseableIterable;\n", + "import org.apache.iceberg.data.Record;\n", + "import org.apache.iceberg.data.IcebergGenerics;\n", + "\n", + "CloseableIterable result = IcebergGenerics.read(tbl).build();\n", + "for (Record r: result) {\n", + " System.out.println(r);\n", + "}" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Java", + "language": "java", + "name": "java" + }, + "language_info": { + "codemirror_mode": "java", + "file_extension": ".jshell", + "mimetype": "text/x-java-source", + "name": "Java", + "pygments_lexer": "java", + "version": "11.0.15+10-post-Debian-1deb11u1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Berlin Buzzwords 2023.ipynb b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Berlin Buzzwords 2023.ipynb new file mode 100644 index 0000000000..66eaad26b1 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Berlin Buzzwords 2023.ipynb @@ -0,0 +1,361 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1041ae6f", + "metadata": {}, + "source": [ + "![iceberg-logo](https://www.apache.org/logos/res/iceberg/iceberg.png)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6a5c8206", + "metadata": {}, + "outputs": [], + "source": [ + "from pyspark.sql import SparkSession\n", + "spark = SparkSession.builder.appName(\"Jupyter\").getOrCreate()\n", + "\n", + "spark" + ] + }, + { + "cell_type": "markdown", + "id": "6f9a9f41", + "metadata": {}, + "source": [ + "## Load Two Months of NYC Taxi/Limousine Trip Data\n", + "\n", + "For this notebook, we will use the New York City Taxi and Limousine Commision Trip Record Data that's available on the AWS Open Data Registry. This contains data of trips taken by taxis and for-hire vehicles in New York City. We'll save this into an iceberg table called `taxis`." + ] + }, + { + "cell_type": "markdown", + "id": "747bee98", + "metadata": {}, + "source": [ + "To be able to rerun the notebook several times, let's drop the table if it exists to start fresh." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "930682ce", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "CREATE DATABASE IF NOT EXISTS nyc.taxis;" + ] + }, + { + "cell_type": "markdown", + "id": "5816de2e", + "metadata": {}, + "source": [ + "## First create the table" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "22ac5552", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DROP TABLE IF EXISTS nyc.taxis;" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f918310a", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "CREATE TABLE nyc.taxis (\n", + " VendorID bigint,\n", + " tpep_pickup_datetime timestamp,\n", + " tpep_dropoff_datetime timestamp,\n", + " passenger_count double,\n", + " trip_distance double,\n", + " RatecodeID double,\n", + " store_and_fwd_flag string,\n", + " PULocationID bigint,\n", + " DOLocationID bigint,\n", + " payment_type bigint,\n", + " fare_amount double,\n", + " extra double,\n", + " mta_tax double,\n", + " tip_amount double,\n", + " tolls_amount double,\n", + " improvement_surcharge double,\n", + " total_amount double,\n", + " congestion_surcharge double,\n", + " airport_fee double\n", + ")\n", + "USING iceberg\n", + "PARTITIONED BY (days(tpep_pickup_datetime))" + ] + }, + { + "cell_type": "markdown", + "id": "fcba103e", + "metadata": {}, + "source": [ + "# Write a month of data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1c37ca92", + "metadata": {}, + "outputs": [], + "source": [ + "df = spark.read.parquet(\"/home/iceberg/data/yellow_tripdata_2022-01.parquet\")\n", + "df.writeTo(\"nyc.taxis\").append()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a69152aa", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT *\n", + "FROM nyc.taxis" + ] + }, + { + "cell_type": "markdown", + "id": "6fce6bb4", + "metadata": {}, + "source": [ + "## Metadata Tables\n", + "\n", + "Iceberg tables contain very rich metadata that can be easily queried. For example, you can retrieve the manifest list for any snapshot, simply by querying the table's `snapshots` table." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8fade1a3", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT *\n", + "FROM nyc.taxis.snapshots" + ] + }, + { + "cell_type": "markdown", + "id": "4aa4a9cd", + "metadata": {}, + "source": [ + "# Write a month of data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ed7a7b8f", + "metadata": {}, + "outputs": [], + "source": [ + "df = spark.read.parquet(\"/home/iceberg/data/yellow_tripdata_2022-02.parquet\")\n", + "df.writeTo(\"nyc.taxis\").append()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fbfb160c", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT *\n", + "FROM nyc.taxis.snapshots\n", + "ORDER BY committed_at DESC" + ] + }, + { + "cell_type": "markdown", + "id": "65deb074", + "metadata": {}, + "source": [ + "## Manifest lists\n", + "\n", + "Now we'll list all the manifests. This is the abovemention `manifest_list` of the current snapshot." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bab64f90", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT *\n", + "FROM nyc.taxis.manifests" + ] + }, + { + "cell_type": "markdown", + "id": "b11e64c9", + "metadata": {}, + "source": [ + "# Manifests\n", + "\n", + "The next layer is the manifests that has references to the Parquet files." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1c4a942c", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT *\n", + "FROM nyc.taxis.files" + ] + }, + { + "cell_type": "markdown", + "id": "31567e4e", + "metadata": {}, + "source": [ + "# Flexibility of partitioning\n", + "\n", + "We can easily change the partitioning of the table" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "156885c7", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT * FROM nyc.taxis.partitions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "184604d9", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER TABLE nyc.taxis DROP PARTITION FIELD days(tpep_pickup_datetime)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c26dddb5", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER TABLE nyc.taxis ADD PARTITION FIELD hours(tpep_pickup_datetime)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42ec7b70", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT * FROM nyc.taxis.partitions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6d5dea98", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "CALL system.rewrite_data_files('nyc.taxis')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5fdf3a22", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT *\n", + "FROM nyc.taxis.files" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "40447a02", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT *\n", + "FROM nyc.taxis.snapshots\n", + "ORDER BY committed_at DESC" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.17" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Getting Started.ipynb b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Getting Started.ipynb new file mode 100644 index 0000000000..fc817202e6 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Getting Started.ipynb @@ -0,0 +1,509 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1041ae6f", + "metadata": {}, + "source": [ + "![iceberg-logo](https://www.apache.org/logos/res/iceberg/iceberg.png)" + ] + }, + { + "cell_type": "markdown", + "id": "247fb2ab", + "metadata": {}, + "source": [ + "### [Docker, Spark, and Iceberg: The Fastest Way to Try Iceberg!](https://tabular.io/blog/docker-spark-and-iceberg/)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6a5c8206", + "metadata": {}, + "outputs": [], + "source": [ + "from pyspark.sql import SparkSession\n", + "spark = SparkSession.builder.appName(\"Jupyter\").getOrCreate()\n", + "\n", + "spark" + ] + }, + { + "cell_type": "markdown", + "id": "6f9a9f41", + "metadata": {}, + "source": [ + "## Load One Month of NYC Taxi/Limousine Trip Data\n", + "\n", + "For this notebook, we will use the New York City Taxi and Limousine Commision Trip Record Data that's available on the AWS Open Data Registry. This contains data of trips taken by taxis and for-hire vehicles in New York City. We'll save this into an iceberg table called `taxis`." + ] + }, + { + "cell_type": "markdown", + "id": "747bee98", + "metadata": {}, + "source": [ + "To be able to rerun the notebook several times, let's drop the table if it exists to start fresh." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "930682ce", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "CREATE DATABASE IF NOT EXISTS nyc" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f918310a", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DROP TABLE IF EXISTS nyc.taxis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1c37ca92", + "metadata": {}, + "outputs": [], + "source": [ + "df = spark.read.parquet(\"/home/iceberg/data/yellow_tripdata_2021-04.parquet\")\n", + "df.write.saveAsTable(\"nyc.taxis\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9fddb808", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DESCRIBE EXTENDED nyc.taxis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bcf99fb3", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT COUNT(*) as cnt\n", + "FROM nyc.taxis" + ] + }, + { + "cell_type": "markdown", + "id": "cffd2c03", + "metadata": {}, + "source": [ + "## Schema Evolution\n", + "\n", + "Adding, dropping, renaming, or altering columns is easy and safe in Iceberg. In this example, we'll rename `fare_amount` to `fare` and `trip_distance` to `distance`. We'll also add a float column `fare_per_distance_unit` immediately after `distance`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "efee8252", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER TABLE nyc.taxis RENAME COLUMN fare_amount TO fare" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "794de3a0", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER TABLE nyc.taxis RENAME COLUMN trip_distance TO distance" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "adac7564", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER TABLE nyc.taxis ALTER COLUMN distance COMMENT 'The elapsed trip distance in miles reported by the taximeter.'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "32d7e6ef", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER TABLE nyc.taxis ALTER COLUMN distance TYPE double;" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6fb4b02a", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER TABLE nyc.taxis ALTER COLUMN distance AFTER fare;" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "81f7cc19", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER TABLE nyc.taxis\n", + "ADD COLUMN fare_per_distance_unit float AFTER distance" + ] + }, + { + "cell_type": "markdown", + "id": "9416b498", + "metadata": {}, + "source": [ + "Let's update the new `fare_per_distance_unit` to equal `fare` divided by `distance`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18771ccb", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "UPDATE nyc.taxis\n", + "SET fare_per_distance_unit = fare/distance" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "09c72ca5", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT\n", + "VendorID\n", + ",tpep_pickup_datetime\n", + ",tpep_dropoff_datetime\n", + ",fare\n", + ",distance\n", + ",fare_per_distance_unit\n", + "FROM nyc.taxis" + ] + }, + { + "cell_type": "markdown", + "id": "37582e02", + "metadata": {}, + "source": [ + "## Expressive SQL for Row Level Changes\n", + "With Iceberg tables, `DELETE` queries can be used to perform row-level deletes. This is as simple as providing the table name and a `WHERE` predicate. If the filter matches an entire partition of the table, Iceberg will intelligently perform a metadata-only operation where it simply deletes the metadata for that partition.\n", + "\n", + "Let's perform a row-level delete for all rows that have a `fare_per_distance_unit` greater than 4 or a `distance` greater than 2. This should leave us with relatively short trips that have a relatively high fare per distance traveled." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ded820f1", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DELETE FROM nyc.taxis\n", + "WHERE fare_per_distance_unit > 4.0 OR distance > 2.0" + ] + }, + { + "cell_type": "markdown", + "id": "faef3712", + "metadata": {}, + "source": [ + "There are some fares that have a `null` for `fare_per_distance_unit` due to the distance being `0`. Let's remove those as well." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18b69265", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DELETE FROM nyc.taxis\n", + "WHERE fare_per_distance_unit is null" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7b92d7db", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT\n", + "VendorID\n", + ",tpep_pickup_datetime\n", + ",tpep_dropoff_datetime\n", + ",fare\n", + ",distance\n", + ",fare_per_distance_unit\n", + "FROM nyc.taxis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6d5472b7", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT COUNT(*) as cnt\n", + "FROM nyc.taxis" + ] + }, + { + "cell_type": "markdown", + "id": "c4b157e5", + "metadata": {}, + "source": [ + "## Partitioning\n", + "\n", + "A table’s partitioning can be updated in place and applied only to newly written data. Query plans are then split, using the old partition scheme for data written before the partition scheme was changed, and using the new partition scheme for data written after. People querying the table don’t even have to be aware of this split. Simple predicates in WHERE clauses are automatically converted to partition filters that prune out files with no matches. This is what’s referred to in Iceberg as *Hidden Partitioning*." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "30e3e3b7", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER TABLE nyc.taxis\n", + "ADD PARTITION FIELD VendorID" + ] + }, + { + "cell_type": "markdown", + "id": "6fce6bb4", + "metadata": {}, + "source": [ + "## Metadata Tables\n", + "\n", + "Iceberg tables contain very rich metadata that can be easily queried. For example, you can retrieve the manifest list for any snapshot, simply by querying the table's `snapshots` table." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8fade1a3", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT snapshot_id, manifest_list\n", + "FROM nyc.taxis.snapshots" + ] + }, + { + "cell_type": "markdown", + "id": "64887133", + "metadata": {}, + "source": [ + "The `files` table contains loads of information on data files, including column level statistics such as null counts, lower bounds, and upper bounds." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1cb712f7", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT file_path, file_format, record_count, null_value_counts, lower_bounds, upper_bounds\n", + "FROM nyc.taxis.files" + ] + }, + { + "cell_type": "markdown", + "id": "65deb074", + "metadata": {}, + "source": [ + "## Time Travel\n", + "\n", + "The history table lists all snapshots and which parent snapshot they derive from. The `is_current_ancestor` flag let's you know if a snapshot is part of the linear history of the current snapshot of the table." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bab64f90", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT *\n", + "FROM nyc.taxis.history" + ] + }, + { + "cell_type": "markdown", + "id": "47129d69", + "metadata": {}, + "source": [ + "You can time-travel by altering the `current-snapshot-id` property of the table to reference any snapshot in the table's history. Let's revert the table to it's original state by traveling to the very first snapshot ID." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4c360238", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql --var df\n", + "\n", + "SELECT *\n", + "FROM nyc.taxis.history" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8df43d00", + "metadata": {}, + "outputs": [], + "source": [ + "original_snapshot = df.head().snapshot_id\n", + "spark.sql(f\"CALL system.rollback_to_snapshot('nyc.taxis', {original_snapshot})\")\n", + "original_snapshot" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "955a4c52", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT\n", + "VendorID\n", + ",tpep_pickup_datetime\n", + ",tpep_dropoff_datetime\n", + ",fare\n", + ",distance\n", + ",fare_per_distance_unit\n", + "FROM nyc.taxis" + ] + }, + { + "cell_type": "markdown", + "id": "67b71c76", + "metadata": {}, + "source": [ + "Another look at the history table shows that the original state of the table has been added as a new entry\n", + "with the original snapshot ID." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91b801d3", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT *\n", + "FROM nyc.taxis.history" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "85667efc", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT COUNT(*) as cnt\n", + "FROM nyc.taxis" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Integrated Audits Demo.ipynb b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Integrated Audits Demo.ipynb new file mode 100644 index 0000000000..4b60b35e45 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Integrated Audits Demo.ipynb @@ -0,0 +1,626 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1041ae6f", + "metadata": {}, + "source": [ + "![iceberg-logo](https://www.apache.org/logos/res/iceberg/iceberg.png)" + ] + }, + { + "cell_type": "markdown", + "id": "247fb2ab", + "metadata": {}, + "source": [ + "### [Integrated Audits: Streamlined Data Observability with Apache Iceberg](https://tabular.io/blog/integrated-audits/)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fd61c16f", + "metadata": {}, + "outputs": [], + "source": [ + "from pyspark.sql import SparkSession\n", + "spark = SparkSession.builder.appName(\"Jupyter\").getOrCreate()\n", + "\n", + "spark" + ] + }, + { + "cell_type": "markdown", + "id": "747bee98", + "metadata": {}, + "source": [ + "To be able to rerun the notebook several times, let's drop the `permits` table if it exists to start fresh." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "26245f7e", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "CREATE DATABASE IF NOT EXISTS nyc" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "08a13fcc", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DROP TABLE IF EXISTS nyc.permits" + ] + }, + { + "cell_type": "markdown", + "id": "eead44c0", + "metadata": {}, + "source": [ + "# Load NYC Film Permits Data" + ] + }, + { + "cell_type": "markdown", + "id": "6f9a9f41", + "metadata": {}, + "source": [ + "For this demo, we will use the [New York City Film Permits dataset](https://data.cityofnewyork.us/City-Government/Film-Permits/tg4x-b46p) available as part of the NYC Open Data initiative. We're using a locally saved copy of a 1000 record sample, but feel free to download the entire dataset to use in this notebook!\n", + "\n", + "We'll save the sample dataset into an iceberg table called `permits`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3cc669a", + "metadata": {}, + "outputs": [], + "source": [ + "df = spark.read.option(\"inferSchema\",\"true\").option(\"multiline\",\"true\").json(\"/home/iceberg/data/nyc_film_permits.json\")\n", + "df.write.saveAsTable(\"nyc.permits\")" + ] + }, + { + "cell_type": "markdown", + "id": "378cf187", + "metadata": {}, + "source": [ + "Taking a quick peek at the data, you can see that there are a number of permits for different boroughs in New York." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3170161", + "metadata": {}, + "outputs": [], + "source": [ + "spark.read \\\n", + " .format(\"iceberg\") \\\n", + " .load(\"nyc.permits\") \\\n", + " .groupBy(\"borough\") \\\n", + " .count() \\\n", + " .show()" + ] + }, + { + "cell_type": "markdown", + "id": "c85a71a2", + "metadata": {}, + "source": [ + "# Generate an ID for an Integrated Audit Session" + ] + }, + { + "cell_type": "markdown", + "id": "182510da", + "metadata": {}, + "source": [ + "An integrated audit session is a single cadence of:\n", + "1. Staging changes to a table\n", + "2. Auditing the staged changes\n", + "3. Committing the changes (optional)\n", + "\n", + "Each of these sessions must be represented with an ID. You can use any convention that makes sense in your environment but in this demo we'll simply use a UUID." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0e39d3d1", + "metadata": {}, + "outputs": [], + "source": [ + "import uuid\n", + "ia_session_id = uuid.uuid4().hex\n", + "ia_session_id" + ] + }, + { + "cell_type": "markdown", + "id": "fa31a9ea", + "metadata": {}, + "source": [ + "# The Setup" + ] + }, + { + "cell_type": "markdown", + "id": "d845953b", + "metadata": {}, + "source": [ + "Tables by default are not configured to allow integrated audits, therefore the first step is enabling this by setting the `write.wap.enabled` table metadata property to `true`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bf29df0b", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER TABLE nyc.permits\n", + "SET TBLPROPERTIES (\n", + " 'write.wap.enabled'='true'\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "1dc5ad69", + "metadata": {}, + "source": [ + "Next, the `spark.wap.id` property of your Spark session configuration must be set to the integrated audit session ID." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "65bc4280", + "metadata": {}, + "outputs": [], + "source": [ + "spark.conf.set('spark.wap.id', ia_session_id)" + ] + }, + { + "cell_type": "markdown", + "id": "3a34995b", + "metadata": {}, + "source": [ + "With a `spark.wap.id` value set, you can now safely write **directly to the permits table**--don't worry, these changes will only be staged, not committed!" + ] + }, + { + "cell_type": "markdown", + "id": "437088f6", + "metadata": {}, + "source": [ + "# Staging The Changes" + ] + }, + { + "cell_type": "markdown", + "id": "1c9fa6e9", + "metadata": {}, + "source": [ + "To stage the changes, you simply write directly to the `permits` table. This is awesome in situations where you're working with a large and complex data ingestion pipeline.\n", + "Instead of including hard-coded logic in your pipeline to switch between a sort of \"audit-mode\" as opposed to \"production-mode\", with integrated audits you simple run your\n", + "production code!\n", + "\n", + "For this demo, let's use a simple query that deletes all records for film permits in the manhattan borough." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14843243", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DELETE FROM nyc.permits\n", + "WHERE borough='Manhattan'" + ] + }, + { + "cell_type": "markdown", + "id": "56cc8478", + "metadata": {}, + "source": [ + "As described, even though the query was executed against the production table, these changes are only staged and not committed since we are within an integrated audit session. Let's confirm this by verifying that a count by borough still includes the Manhattan records." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "95df15e9", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT borough, count(*) permit_cnt\n", + "FROM nyc.permits\n", + "GROUP BY borough" + ] + }, + { + "cell_type": "markdown", + "id": "3fe2c863", + "metadata": {}, + "source": [ + "# The Audit" + ] + }, + { + "cell_type": "markdown", + "id": "a7935b0d", + "metadata": {}, + "source": [ + "Once the changes for this session are staged, you can perform all of your audits to validate the data. The first step is to retrieve the snapshot ID generated by the changes and tagged with this integrated audit session ID." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "95d71430", + "metadata": {}, + "outputs": [], + "source": [ + "query = f\"\"\"\n", + "SELECT snapshot_id\n", + "FROM nyc.permits.snapshots\n", + "WHERE summary['wap.id'] = '{ia_session_id}'\n", + "\"\"\"\n", + "\n", + "ia_session_snapshot = spark.sql(query).head().snapshot_id" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1035b246", + "metadata": {}, + "outputs": [], + "source": [ + "ia_session_snapshot" + ] + }, + { + "cell_type": "markdown", + "id": "4c602800", + "metadata": {}, + "source": [ + "This snapshot includes the staged (but not commited) changes to your production table. Once you have this snapshot ID, you can use Iceberg's Time Travel feature to query it!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c95130e9", + "metadata": {}, + "outputs": [], + "source": [ + "spark.read \\\n", + " .option(\"snapshot-id\", ia_session_snapshot) \\\n", + " .format(\"iceberg\") \\\n", + " .load(\"nyc.permits\") \\\n", + " .groupBy(\"borough\") \\\n", + " .count() \\\n", + " .show()" + ] + }, + { + "cell_type": "markdown", + "id": "0cab3813", + "metadata": {}, + "source": [ + "At this point, you can use any auditing tool or technique to validate your changes. For this demo, we'll do a simple audit that confirms that the only remaining boroughs are Queens, Brooklyn, Bronx, and Staten Island. If either borough is missing or any additional boroughs are found, we'll raise an exception." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "82af5de3", + "metadata": {}, + "outputs": [], + "source": [ + "expected_boroughs = {\"Queens\", \"Brooklyn\", \"Bronx\", \"Staten Island\"}\n", + "distinct_boroughs = spark.read \\\n", + " .option(\"snapshot-id\", ia_session_snapshot) \\\n", + " .format(\"iceberg\") \\\n", + " .load(\"nyc.permits\") \\\n", + " .select(\"borough\") \\\n", + " .distinct() \\\n", + " .toLocalIterator()\n", + "boroughs = {row[0] for row in distinct_boroughs}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a4fad7c2", + "metadata": {}, + "outputs": [], + "source": [ + "# Since `boroughs` and `required_boroughs` are both sets (array of distinct items),\n", + "# we can confirm that they match by checking that the lengths of the sets are equal\n", + "# to eachother as well as to the union of both sets.\n", + "if len(boroughs) != len(expected_boroughs) != len(set.union(boroughs, expected_boroughs)):\n", + " raise ValueError(f\"Audit failed, borough set does not match expected boroughs: {boroughs} != {expected_boroughs}\")" + ] + }, + { + "cell_type": "markdown", + "id": "b1032255", + "metadata": {}, + "source": [ + "If the above check does not fail, we can go ahead and commit our staged data to publish our changes!" + ] + }, + { + "cell_type": "markdown", + "id": "2079435b", + "metadata": {}, + "source": [ + "# The Publish" + ] + }, + { + "cell_type": "markdown", + "id": "88d59f50", + "metadata": {}, + "source": [ + "After the audits are completed, publishing the data is as simple as running a `cherrypick_snapshot` stored procedure." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "056236ba", + "metadata": {}, + "outputs": [], + "source": [ + "publish_query = f\"CALL system.cherrypick_snapshot('nyc.permits', {ia_session_snapshot})\"\n", + "%sql $publish_query" + ] + }, + { + "cell_type": "markdown", + "id": "17b868e8", + "metadata": {}, + "source": [ + "That's it! Publishing the changes from this integrated audit session is a simple metadata-only operation that instantly makes the changes live for all downstream consumers querying the `permits` table! Query results will now include the commit that removed all Manhattan records." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "930682ce", + "metadata": {}, + "outputs": [], + "source": [ + "spark.read \\\n", + " .format(\"iceberg\") \\\n", + " .load(\"nyc.permits\") \\\n", + " .groupBy(\"borough\") \\\n", + " .count() \\\n", + " .show()" + ] + }, + { + "cell_type": "markdown", + "id": "d941b990", + "metadata": {}, + "source": [ + "# What Happens When The Audits Fail?" + ] + }, + { + "cell_type": "markdown", + "id": "f6b4084e", + "metadata": {}, + "source": [ + "What about when your audits fail? What happens to the snapshots generated? How about the data and metadata files?\n", + "\n", + "One of the best parts of Iceberg's integrated audits is that the cleanup of \"*staged-yet-not-committed-data*\" is part of the normal snapshot cleanup process of a typical Iceberg warehouse. To be more specific, let's say a daily snapshot expiration is performed on the data warehouse (using the [expire_snapshots](https://iceberg.apache.org/docs/latest/spark-procedures/#expire_snapshots) procedure) and all snapshots older than 7 days are expired. That means once your staged snapshot reaches 7 days in age, it will be expired.\n", + "\n", + "Additionally, since the changes were never committed, the underlying data files for the snapshot will be removed since they're not referenced by any other snapshots in the linear history of the table.\n", + "\n", + "Let's see this in action. First, start a new integrated audit session and stage a commit by inserting a single record." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "25eff1ef", + "metadata": {}, + "outputs": [], + "source": [ + "ia_session_id = uuid.uuid4().hex\n", + "ia_session_id" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4726b169", + "metadata": {}, + "outputs": [], + "source": [ + "spark.conf.set('spark.wap.id', ia_session_id)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31bf19f1", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "INSERT INTO nyc.permits\n", + "VALUES (\n", + " 'Hoboken',\n", + " 'Television',\n", + " '1',\n", + " 'United States of America',\n", + " '2021-11-24T23:00:00.000',\n", + " '2021-11-23T09:38:17.000',\n", + " 'Mayor\\'s Office of Film, Theatre & Broadcasting',\n", + " '613322',\n", + " 'Shooting Permit',\n", + " 'WASHINGTON STREET',\n", + " '100',\n", + " '2021-11-24T07:00:00.000',\n", + " 'Episodic series',\n", + " '07030'\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "aa29184b", + "metadata": {}, + "source": [ + "Next, let's identify the snapshot that was tagged with the integrated audit session ID." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "682a5f52", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT snapshot_id\n", + "FROM nyc.permits.snapshots" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ef4dd148", + "metadata": {}, + "outputs": [], + "source": [ + "query = f\"\"\"\n", + "SELECT snapshot_id\n", + "FROM nyc.permits.snapshots\n", + "WHERE summary['wap.id'] = '{ia_session_id}'\n", + "\"\"\"\n", + "\n", + "ia_session_snapshot = spark.sql(query).head().snapshot_id" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "62f52c08", + "metadata": {}, + "outputs": [], + "source": [ + "ia_session_snapshot" + ] + }, + { + "cell_type": "markdown", + "id": "60561dff", + "metadata": {}, + "source": [ + "A quick check of the history table shows that this snapshot is not included as part of the current history of the table since it has not been published yet." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ec96a9c0", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT *\n", + "FROM nyc.permits.history" + ] + }, + { + "cell_type": "markdown", + "id": "6ec54f3a", + "metadata": {}, + "source": [ + "In a scenario where the audits fail and this change is not published, the `expire_snapshots` procedure will clean up the snapshot **and** the data files. Let's demonstrate this by calling the `expire_snapshots` procedure for all snapshots older than the current timestamp." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4727c61e", + "metadata": {}, + "outputs": [], + "source": [ + "import time\n", + "%sql CALL system.expire_snapshots('nyc.permits', {round(time.time() * 1000)}, 100)" + ] + }, + { + "cell_type": "markdown", + "id": "c8e47351", + "metadata": {}, + "source": [ + "The output from the `expire_snapshots` procedure shows that a data file, a manifest file, and a manifest list file were deleted. Furthermore, the snapshot no longer appears in the permit table's snapshots table." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "53f53072", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT *\n", + "FROM nyc.permits.snapshots" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Table Maintenance Spark Procedures.ipynb b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Table Maintenance Spark Procedures.ipynb new file mode 100644 index 0000000000..8f3192b495 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Table Maintenance Spark Procedures.ipynb @@ -0,0 +1,220 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1041ae6f", + "metadata": {}, + "source": [ + "![iceberg-logo](https://www.apache.org/logos/res/iceberg/iceberg.png)" + ] + }, + { + "cell_type": "markdown", + "id": "247fb2ab", + "metadata": {}, + "source": [ + "### [Table Maintenance: The Key To Keeping Your Iceberg Tables Healthy and Performant](https://tabular.io/blog/table-maintenance/)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6a5c8206", + "metadata": {}, + "outputs": [], + "source": [ + "spark" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1dab5ef0", + "metadata": {}, + "outputs": [], + "source": [ + "spark.sql(\"DROP TABLE IF EXISTS demo.nyc.taxis_sample\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "49a45d0b", + "metadata": {}, + "outputs": [], + "source": [ + "spark.sql(\"\"\"\n", + "CREATE TABLE demo.nyc.taxis_sample (\n", + " `VendorID` BIGINT,\n", + " `tpep_pickup_datetime` TIMESTAMP,\n", + " `tpep_dropoff_datetime` TIMESTAMP,\n", + " `passenger_count` DOUBLE,\n", + " `trip_distance` DOUBLE,\n", + " `RatecodeID` DOUBLE,\n", + " `store_and_fwd_flag` STRING,\n", + " `PULocationID` BIGINT,\n", + " `DOLocationID` BIGINT,\n", + " `payment_type` BIGINT,\n", + " `fare_amount` DOUBLE,\n", + " `extra` DOUBLE,\n", + " `mta_tax` DOUBLE,\n", + " `tip_amount` DOUBLE,\n", + " `tolls_amount` DOUBLE,\n", + " `improvement_surcharge` DOUBLE,\n", + " `total_amount` DOUBLE,\n", + " `congestion_surcharge` DOUBLE,\n", + " `airport_fee` DOUBLE)\n", + "USING iceberg\n", + "TBLPROPERTIES(\n", + " 'write.target-file-size-bytes'='5242880'\n", + ")\n", + "\"\"\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "997bb9df", + "metadata": {}, + "outputs": [], + "source": [ + "val df_202201 = spark.read.parquet(\"/home/iceberg/data/yellow_tripdata_2022-01.parquet\")\n", + "val df_202202 = spark.read.parquet(\"/home/iceberg/data/yellow_tripdata_2022-02.parquet\")\n", + "val df_202203 = spark.read.parquet(\"/home/iceberg/data/yellow_tripdata_2022-03.parquet\")\n", + "val df_q1 = df_202201.union(df_202202).union(df_202203)\n", + "df_q1.write.insertInto(\"nyc.taxis_sample\")" + ] + }, + { + "cell_type": "markdown", + "id": "78cab088", + "metadata": {}, + "source": [ + "## Rewriting Data Files" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7ad64e6b", + "metadata": {}, + "outputs": [], + "source": [ + "spark.sql(\"SELECT file_path, file_size_in_bytes FROM nyc.taxis_sample.files\").show(100)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d5d10355", + "metadata": {}, + "outputs": [], + "source": [ + "spark.sql(\"ALTER TABLE nyc.taxis_sample UNSET TBLPROPERTIES ('write.target-file-size-bytes')\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f26228a5", + "metadata": {}, + "outputs": [], + "source": [ + "spark.sql(\"CALL demo.system.rewrite_data_files(table => 'nyc.taxis_sample', options => map('target-file-size-bytes','52428800'))\").show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43a9ed67", + "metadata": {}, + "outputs": [], + "source": [ + "spark.sql(\"SELECT file_path, file_size_in_bytes FROM nyc.taxis_sample.files\").show(100)" + ] + }, + { + "cell_type": "markdown", + "id": "523eb893", + "metadata": {}, + "source": [ + "## Expiring Snapshots" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "98e8c5db", + "metadata": {}, + "outputs": [], + "source": [ + "spark.sql(\"SELECT committed_at, snapshot_id, operation FROM nyc.taxis_sample.snapshots\").show(truncate=false)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b264c989", + "metadata": {}, + "outputs": [], + "source": [ + "val now = java.util.Calendar.getInstance().getTime()\n", + "val format = new java.text.SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss.SSS\")\n", + "val now_str = format.format(now)\n", + "\n", + "spark.sql(s\"CALL demo.system.expire_snapshots(table => 'nyc.taxis_sample', older_than => TIMESTAMP '$now_str', retain_last => 1)\").show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "131e1f09", + "metadata": {}, + "outputs": [], + "source": [ + "spark.sql(\"SELECT committed_at, snapshot_id, operation FROM nyc.taxis_sample.snapshots\").show(truncate=false)" + ] + }, + { + "cell_type": "markdown", + "id": "181212b6", + "metadata": {}, + "source": [ + "## Rewriting Manifest Files" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "49290e56", + "metadata": {}, + "outputs": [], + "source": [ + "spark.sql(\"CALL demo.system.rewrite_manifests('nyc.taxis_sample')\").show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "spylon-kernel", + "language": "scala", + "name": "spylon-kernel" + }, + "language_info": { + "codemirror_mode": "text/x-scala", + "file_extension": ".scala", + "help_links": [ + { + "text": "MetaKernel Magics", + "url": "https://metakernel.readthedocs.io/en/latest/source/README.html" + } + ], + "mimetype": "text/x-scala", + "name": "scala", + "pygments_lexer": "scala", + "version": "0.4.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - View Support.ipynb b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - View Support.ipynb new file mode 100644 index 0000000000..fa8dd7f6bb --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - View Support.ipynb @@ -0,0 +1,525 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1041ae6f", + "metadata": {}, + "source": [ + "![iceberg-logo](https://www.apache.org/logos/res/iceberg/iceberg.png)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6a5c8206", + "metadata": {}, + "outputs": [], + "source": [ + "from pyspark.sql import SparkSession\n", + "spark = SparkSession.builder.appName(\"Jupyter\").getOrCreate()\n", + "\n", + "spark" + ] + }, + { + "cell_type": "markdown", + "id": "6f9a9f41", + "metadata": {}, + "source": [ + "## Load Two Months of NYC Taxi/Limousine Trip Data\n", + "\n", + "This notebook uses the New York City Taxi and Limousine Commission Trip Record Data available on the AWS Open Data Registry. This contains data of trips taken by taxis and for-hire vehicles in New York City. This data is stored in an iceberg table called `taxis`." + ] + }, + { + "cell_type": "markdown", + "id": "747bee98", + "metadata": {}, + "source": [ + "To be able to rerun the notebook several times, let's drop the table and the views if they exist to start fresh." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "930682ce", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "CREATE DATABASE IF NOT EXISTS nyc.taxis;" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "22ac5552", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DROP TABLE IF EXISTS nyc.taxis\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4cf5b4c0-89ac-4f79-8beb-fc55554bab22", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DROP VIEW IF EXISTS nyc.long_distances" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5a443155-85fe-4e7a-8216-9669e0765c93", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DROP VIEW IF EXISTS nyc.negative_amounts" + ] + }, + { + "cell_type": "markdown", + "id": "5816de2e", + "metadata": {}, + "source": [ + "## Create the table" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f918310a", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "CREATE TABLE nyc.taxis (\n", + " VendorID bigint,\n", + " tpep_pickup_datetime timestamp,\n", + " tpep_dropoff_datetime timestamp,\n", + " passenger_count double,\n", + " trip_distance double,\n", + " RatecodeID double,\n", + " store_and_fwd_flag string,\n", + " PULocationID bigint,\n", + " DOLocationID bigint,\n", + " payment_type bigint,\n", + " fare_amount double,\n", + " extra double,\n", + " mta_tax double,\n", + " tip_amount double,\n", + " tolls_amount double,\n", + " improvement_surcharge double,\n", + " total_amount double,\n", + " congestion_surcharge double,\n", + " airport_fee double\n", + ")\n", + "USING iceberg\n", + "PARTITIONED BY (days(tpep_pickup_datetime))" + ] + }, + { + "cell_type": "markdown", + "id": "fcba103e", + "metadata": {}, + "source": [ + "# Write a month of data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1c37ca92", + "metadata": {}, + "outputs": [], + "source": [ + "df = spark.read.parquet(\"/home/iceberg/data/yellow_tripdata_2022-01.parquet\")\n", + "df.writeTo(\"nyc.taxis\").append()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a69152aa", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT * FROM nyc.taxis" + ] + }, + { + "cell_type": "markdown", + "id": "fd854d56-33d5-46a5-b552-869479b8e188", + "metadata": {}, + "source": [ + "# Create a view\n", + "\n", + "Let's create an Iceberg view to look at the longest distances travelled and the total amount of the trips." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8fade1a3", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "CREATE VIEW nyc.long_distances (\n", + " vendor_id COMMENT 'Vendor ID',\n", + " pickup_date,\n", + " dropoff_date,\n", + " distance COMMENT 'Trip Distance',\n", + " total COMMENT 'Total amount')\n", + " AS SELECT VendorID, tpep_pickup_datetime, tpep_dropoff_datetime, trip_distance, total_amount FROM nyc.taxis ORDER BY trip_distance" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cfee5d8f-f862-4aa3-a096-8ff9ea66ba26", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT * FROM nyc.long_distances" + ] + }, + { + "cell_type": "markdown", + "id": "6fce6bb4", + "metadata": {}, + "source": [ + "## Update View to order results differently\n", + "\n", + "The output isn't as helpful as imagined, so let's update the view and change the order of columns and the ordering of the results." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "74c10267-d65b-4650-ab92-02a978f5872a", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "CREATE OR REPLACE VIEW nyc.long_distances (\n", + " distance COMMENT 'Trip Distance',\n", + " total COMMENT 'Total amount',\n", + " vendor_id COMMENT 'Vendor ID',\n", + " pickup_date,\n", + " dropoff_date)\n", + " AS SELECT trip_distance, total_amount, VendorID, tpep_pickup_datetime, tpep_dropoff_datetime\n", + " FROM nyc.taxis\n", + " WHERE trip_distance > 35 ORDER BY total_amount, trip_distance" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0e764a28-297f-4c8d-87dc-45ae63380d6e", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT * FROM nyc.long_distances" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "369b6e37-c7b3-4402-9087-2d9074b53dd7", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT count(*) FROM nyc.long_distances" + ] + }, + { + "cell_type": "markdown", + "id": "4aa4a9cd", + "metadata": {}, + "source": [ + "# Write a month of data\n", + "\n", + "Let's write another month of data and see how the results of the view change" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ed7a7b8f", + "metadata": {}, + "outputs": [], + "source": [ + "df = spark.read.parquet(\"/home/iceberg/data/yellow_tripdata_2022-02.parquet\")\n", + "df.writeTo(\"nyc.taxis\").append()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fbfb160c", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT * FROM nyc.long_distances" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8085d47e-d629-408c-9753-95f58fac23c5", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT count(*) FROM nyc.long_distances" + ] + }, + { + "cell_type": "markdown", + "id": "35bf8f88-a493-42c0-b7a9-3941f8ebf4c8", + "metadata": {}, + "source": [ + "# Create another view\n", + "It appears that there are trips with negative total amounts. Let's display these results in a separate view" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aa47bf43-2460-4990-88df-6040897c3386", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "CREATE OR REPLACE VIEW nyc.negative_amounts (\n", + " total COMMENT 'Total amount',\n", + " distance COMMENT 'Trip Distance',\n", + " vendor_id COMMENT 'Vendor ID',\n", + " pickup_date,\n", + " dropoff_date)\n", + " AS SELECT total_amount, trip_distance, VendorID, tpep_pickup_datetime, tpep_dropoff_datetime\n", + " FROM nyc.taxis\n", + " WHERE total_amount < 0 ORDER BY total_amount" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d6c6a306-1752-4a6d-9213-d5b615110b1d", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT * FROM nyc.negative_amounts" + ] + }, + { + "cell_type": "markdown", + "id": "65deb074", + "metadata": {}, + "source": [ + "# Listing and describing views" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bab64f90", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SHOW VIEWS in nyc" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "be3b1930-e140-4795-81d9-9e5abe626fb7", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SHOW VIEWS in nyc LIKE '*neg*'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dfc2dcb3-4717-4730-94b6-18b9a239cf74", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DESCRIBE nyc.long_distances" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7653ef78-f419-462b-915b-0cbd9f62d473", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DESCRIBE EXTENDED nyc.long_distances" + ] + }, + { + "cell_type": "markdown", + "id": "b11e64c9", + "metadata": {}, + "source": [ + "# Displaying the CREATE statement of a view" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1c4a942c", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SHOW CREATE TABLE nyc.long_distances" + ] + }, + { + "cell_type": "markdown", + "id": "42f6e042-00ce-4277-bf9a-16931f898d7b", + "metadata": {}, + "source": [ + "# Altering and displaying properties of a view\n", + "\n", + "This will add a new property and also update the comment of the view. \n", + "The comment will be shown when describing the view.\n", + "The end of this section will also remove a property from the view." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fa823a4c-ede3-40d7-906e-27818070fa9b", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SHOW TBLPROPERTIES nyc.long_distances" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9c3b2fb4-4db9-408f-a36d-84970108dd5b", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER VIEW nyc.long_distances SET TBLPROPERTIES ('key1' = 'val1', 'key2' = 'val2', 'comment' = 'This is a view comment')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2a8dd804-d222-44e2-92b9-2069868e206a", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SHOW TBLPROPERTIES nyc.long_distances" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1950bd5d-a5fc-4ee1-a4a9-1242261232f0", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DESCRIBE EXTENDED nyc.long_distances" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "88781989-0967-4349-b435-ad193c9697e7", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER VIEW nyc.long_distances UNSET TBLPROPERTIES ('key1')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6864599-b4fa-4525-8304-f1cb3ee7144a", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SHOW TBLPROPERTIES nyc.long_distances" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.18" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Write-Audit-Publish (WAP) with Branches.ipynb b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Write-Audit-Publish (WAP) with Branches.ipynb new file mode 100644 index 0000000000..b534c6e329 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/Iceberg - Write-Audit-Publish (WAP) with Branches.ipynb @@ -0,0 +1,788 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1041ae6f", + "metadata": {}, + "source": [ + "![iceberg-logo](https://www.apache.org/logos/res/iceberg/iceberg.png)" + ] + }, + { + "cell_type": "markdown", + "id": "7b6633c1", + "metadata": {}, + "source": [ + "## Write-Audit-Publish with Branches in Apache Iceberg" + ] + }, + { + "cell_type": "markdown", + "id": "08d9d173", + "metadata": {}, + "source": [ + "This notebook runs using the Docker Compose at https://github.com/tabular-io/docker-spark-iceberg. \n", + "It's based on the [Iceberg - Integrated Audits Demo.ipynb](https://github.com/tabular-io/docker-spark-iceberg/blob/main/spark/notebooks/Iceberg%20-%20Integrated%20Audits%20Demo.ipynb) notebook. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fd61c16f", + "metadata": {}, + "outputs": [], + "source": [ + "from pyspark.sql import SparkSession\n", + "spark = SparkSession.builder.appName(\"Jupyter\").getOrCreate()\n", + "\n", + "spark" + ] + }, + { + "cell_type": "markdown", + "id": "747bee98", + "metadata": {}, + "source": [ + "To be able to rerun the notebook several times, let's drop the `permits` table if it exists to start fresh." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "26245f7e", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "CREATE DATABASE IF NOT EXISTS nyc" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f66e5810", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DROP TABLE IF EXISTS nyc.permits" + ] + }, + { + "cell_type": "markdown", + "id": "eead44c0", + "metadata": {}, + "source": [ + "# Load NYC Film Permits Data" + ] + }, + { + "cell_type": "markdown", + "id": "6f9a9f41", + "metadata": {}, + "source": [ + "For this demo, we will use the [New York City Film Permits dataset](https://data.cityofnewyork.us/City-Government/Film-Permits/tg4x-b46p) available as part of the NYC Open Data initiative. We're using a locally saved copy of a 1000 record sample, but feel free to download the entire dataset to use in this notebook!\n", + "\n", + "We'll save the sample dataset into an iceberg table called `permits`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3cc669a", + "metadata": {}, + "outputs": [], + "source": [ + "df = spark.read.option(\"inferSchema\",\"true\").option(\"multiline\",\"true\").json(\"/home/iceberg/data/nyc_film_permits.json\")\n", + "df.write.saveAsTable(\"nyc.permits\")" + ] + }, + { + "cell_type": "markdown", + "id": "378cf187", + "metadata": {}, + "source": [ + "Taking a quick peek at the data, you can see that there are a number of permits for different boroughs in New York." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3170161", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT borough, count(*) permit_cnt\n", + "FROM nyc.permits\n", + "GROUP BY borough" + ] + }, + { + "cell_type": "markdown", + "id": "fa31a9ea", + "metadata": {}, + "source": [ + "# The Setup" + ] + }, + { + "cell_type": "markdown", + "id": "d845953b", + "metadata": {}, + "source": [ + "Tables by default are not configured to allow integrated audits, therefore the first step is enabling this by setting the `write.wap.enabled` table metadata property to `true`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bf29df0b", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER TABLE nyc.permits\n", + "SET TBLPROPERTIES (\n", + " 'write.wap.enabled'='true'\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "6405f8a7", + "metadata": {}, + "source": [ + "We create a branch for the work we want to do. This is a copy-on-write branch, so \"free\" until we start making changes (and \"cheap\" thereafter) since only data that's changed needs to be written. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14035a18", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER TABLE nyc.permits\n", + "CREATE BRANCH etl_job_42" + ] + }, + { + "cell_type": "markdown", + "id": "437088f6", + "metadata": {}, + "source": [ + "# Write" + ] + }, + { + "cell_type": "markdown", + "id": "a24b066e", + "metadata": {}, + "source": [ + "Before writing to the table we set `spark.wap.branch` so that writes (and reads) are against the specified branch of the table. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "842e361c", + "metadata": {}, + "outputs": [], + "source": [ + "spark.conf.set('spark.wap.branch', 'etl_job_42')" + ] + }, + { + "cell_type": "markdown", + "id": "6b749826", + "metadata": {}, + "source": [ + "Now make the change to the table" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14843243", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DELETE FROM nyc.permits\n", + "WHERE borough='Manhattan'" + ] + }, + { + "cell_type": "markdown", + "id": "8eb688c8", + "metadata": {}, + "source": [ + "## Inspecting the staged/unpublished data" + ] + }, + { + "cell_type": "markdown", + "id": "ce1b1256", + "metadata": {}, + "source": [ + "### Staged/unpublished data" + ] + }, + { + "cell_type": "markdown", + "id": "1c4c04cd", + "metadata": {}, + "source": [ + "The changes are reflected in the table:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dfbd0d4b", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT borough, count(*) permit_cnt\n", + "FROM nyc.permits\n", + "GROUP BY borough" + ] + }, + { + "cell_type": "markdown", + "id": "bf332168", + "metadata": {}, + "source": [ + "Note that because `spark.wap.branch` is set the above query is effectively the same as this one with `VERSION AS OF` for the branch" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1cd4b72b", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT borough, count(*) permit_cnt\n", + "FROM nyc.permits VERSION AS OF 'etl_job_42'\n", + "GROUP BY borough" + ] + }, + { + "cell_type": "markdown", + "id": "0ac96fd0", + "metadata": {}, + "source": [ + "Another syntax (albiet less clear IMHO) for `VERSION AS OF` is a `branch_` suffix to the table: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "169de151", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT borough, count(*) permit_cnt\n", + "FROM nyc.permits.branch_etl_job_42\n", + "GROUP BY borough" + ] + }, + { + "cell_type": "markdown", + "id": "85332bf5", + "metadata": {}, + "source": [ + "### Published data" + ] + }, + { + "cell_type": "markdown", + "id": "5ad40cf1", + "metadata": {}, + "source": [ + "We can also inspect the unmodified `main` version of the table with `VERSION AS OF`: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "95df15e9", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT borough, count(*) permit_cnt\n", + "FROM nyc.permits VERSION AS OF 'main'\n", + "GROUP BY borough" + ] + }, + { + "cell_type": "markdown", + "id": "bf419df3", + "metadata": {}, + "source": [ + "The same `branch_` suffix words here too: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "270c09c6", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT borough, count(*) permit_cnt\n", + "FROM nyc.permits.branch_main\n", + "GROUP BY borough" + ] + }, + { + "cell_type": "markdown", + "id": "c17c824f", + "metadata": {}, + "source": [ + "Any other user of the table will see the full set of data. We can reassure ourselves of this by unsetting `spark.wap.branch` for the session and querying the table without any `VERSION AS OF` modifier" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6e9f7ea3", + "metadata": {}, + "outputs": [], + "source": [ + "spark.conf.unset('spark.wap.branch')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "935d46c8", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT borough, count(*) permit_cnt\n", + "FROM nyc.permits\n", + "GROUP BY borough" + ] + }, + { + "cell_type": "markdown", + "id": "a8ad4c4e", + "metadata": {}, + "source": [ + "# Audit" + ] + }, + { + "cell_type": "markdown", + "id": "ba43c910", + "metadata": {}, + "source": [ + "How you audit the data is up to you. The nice thing about the data being staged is that you can do it within the same ETL job, or have another tool do it. " + ] + }, + { + "cell_type": "markdown", + "id": "90485620", + "metadata": {}, + "source": [ + "Here's a very simple example of doing in Python. We're going to programatically check that only the four expected boroughs remain in the data. \n", + "\n", + "First, we define those that are expected: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9d68a3b1", + "metadata": {}, + "outputs": [], + "source": [ + "expected_boroughs = {\"Queens\", \"Brooklyn\", \"Bronx\"}" + ] + }, + { + "cell_type": "markdown", + "id": "b17dfd72", + "metadata": {}, + "source": [ + "Then we get a set of the actual boroughs in the staged data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3ce3d70a", + "metadata": {}, + "outputs": [], + "source": [ + "distinct_boroughs = spark.read \\\n", + " .option(\"branch\", \"etl_job_42\") \\\n", + " .format(\"iceberg\") \\\n", + " .load(\"nyc.permits\") \\\n", + " .select(\"borough\") \\\n", + " .distinct() \\\n", + " .toLocalIterator()\n", + "boroughs = {row[0] for row in distinct_boroughs}" + ] + }, + { + "cell_type": "markdown", + "id": "4a30827d", + "metadata": {}, + "source": [ + "Now we do two checks: \n", + "\n", + "1. Compare the length of the expected vs actual set\n", + "2. Check that the two sets when unioned are still the same length. This is necessary, since the first test isn't sufficient alone" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aeb78c2b", + "metadata": {}, + "outputs": [], + "source": [ + "if ( (len(boroughs) != len(expected_boroughs)) \\\n", + " or (len(boroughs) != len(set.union(boroughs, expected_boroughs))) \\\n", + " or (len(expected_boroughs) != len(set.union(boroughs, expected_boroughs)))):\n", + " raise ValueError(f\"Audit failed, borough set does not match expected boroughs: {boroughs} != {expected_boroughs}\")\n", + "else:\n", + " print(f\"Audit has passed 🙌🏻\")" + ] + }, + { + "cell_type": "markdown", + "id": "28a18925", + "metadata": {}, + "source": [ + "# Publish" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "7bc16e05", + "metadata": {}, + "source": [ + "Iceberg supports fast-forward merging of branches back to `main`, using the [`manageSnapshots().fastForwardBranch`](https://iceberg.apache.org/javadoc/latest/org/apache/iceberg/ManageSnapshots.html#fastForwardBranch-java.lang.String-java.lang.String-) API.\n", + "\n", + "This isn't yet exposed in Spark, so the existing [`cherrypick`](https://iceberg.apache.org/javadoc/latest/org/apache/iceberg/ManageSnapshots.html#cherrypick-long-) can be used as a slightly less elegant option.\n", + "\n", + "ℹ️ Note that `cherrypick` only works for one commit. " + ] + }, + { + "cell_type": "markdown", + "id": "4619fe57", + "metadata": {}, + "source": [ + "First, we need the snapshot ID of our branch, which we can get from the `.refs` table:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8cd5d318", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT * FROM nyc.permits.refs " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2c5f09f1", + "metadata": {}, + "outputs": [], + "source": [ + "query = f\"\"\"\n", + "SELECT snapshot_id\n", + "FROM nyc.permits.refs\n", + "WHERE name = 'etl_job_42'\n", + "\"\"\"\n", + "\n", + "wap_snapshot_id = spark.sql(query).head().snapshot_id" + ] + }, + { + "cell_type": "markdown", + "id": "58520bc1", + "metadata": {}, + "source": [ + "Now we do the publish, using `cherrypick_snapshot` and the snapshot id:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b93d6f91", + "metadata": {}, + "outputs": [], + "source": [ + "publish_query = f\"CALL system.cherrypick_snapshot('nyc.permits', {wap_snapshot_id})\"\n", + "\n", + "%sql $publish_query" + ] + }, + { + "cell_type": "markdown", + "id": "d7546923", + "metadata": {}, + "source": [ + "Finally, we look at the table and revel in the glory that is our published changes 🎉" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6d62ebc6", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT borough, count(*) permit_cnt\n", + "FROM nyc.permits.branch_etl_job_42\n", + "GROUP BY borough" + ] + }, + { + "cell_type": "markdown", + "id": "0f60be58", + "metadata": {}, + "source": [ + "We can also inspect the unmodified `main` version of the table with `VERSION AS OF`: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "97c7a98e", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT borough, count(*) permit_cnt\n", + "FROM nyc.permits VERSION AS OF 'main'\n", + "GROUP BY borough" + ] + }, + { + "cell_type": "markdown", + "id": "b0072a24", + "metadata": {}, + "source": [ + "---\n", + "\n", + "# What if You Don't Want to Publish Changes?" + ] + }, + { + "cell_type": "markdown", + "id": "441d1e92", + "metadata": {}, + "source": [ + "If you don't want to merge the branch you can simply `DROP` it. " + ] + }, + { + "cell_type": "markdown", + "id": "49dd455a", + "metadata": {}, + "source": [ + "## Create a new branch" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0dd25215", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER TABLE nyc.permits\n", + "CREATE BRANCH new_etl_job" + ] + }, + { + "cell_type": "markdown", + "id": "bc9bac1e", + "metadata": {}, + "source": [ + "## Set `spark.wap.branch`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0b2e2284", + "metadata": {}, + "outputs": [], + "source": [ + "spark.conf.set('spark.wap.branch', 'new_etl_job')" + ] + }, + { + "cell_type": "markdown", + "id": "a5f65ce0", + "metadata": {}, + "source": [ + "## Write" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4dbd6ed3", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "DELETE FROM nyc.permits WHERE borough LIKE '%'" + ] + }, + { + "cell_type": "markdown", + "id": "0344e3d0", + "metadata": {}, + "source": [ + "## Audit" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea44436a", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT borough, count(*) permit_cnt\n", + "FROM nyc.permits \n", + "GROUP BY borough" + ] + }, + { + "cell_type": "markdown", + "id": "b5974d6e", + "metadata": {}, + "source": [ + "### Whoops 🤭 \n", + "We deleted all the data" + ] + }, + { + "cell_type": "markdown", + "id": "74ebb57d", + "metadata": {}, + "source": [ + "### Reassure ourselves that the data is still there in `main`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "87d8ee7e", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "SELECT borough, count(*) permit_cnt\n", + "FROM nyc.permits VERSION AS OF 'main'\n", + "GROUP BY borough" + ] + }, + { + "cell_type": "markdown", + "id": "22d5d357", + "metadata": {}, + "source": [ + "## Abandon changes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0533a1f6", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "ALTER TABLE nyc.permits\n", + "DROP BRANCH new_etl_job" + ] + }, + { + "cell_type": "markdown", + "id": "328ed36c", + "metadata": {}, + "source": [ + "---\n", + "\n", + "# Where Next?" + ] + }, + { + "cell_type": "markdown", + "id": "cca251c2", + "metadata": {}, + "source": [ + "For more information about write-audit-publish see [this talk from Michelle Winters](https://www.youtube.com/watch?v=fXHdeBnpXrg&t=1001s) and [this talk from Sam Redai](https://www.dremio.com/wp-content/uploads/2022/05/Sam-Redai-The-Write-Audit-Publish-Pattern-via-Apache-Iceberg.pdf)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.16" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/PyIceberg - Getting Started.ipynb b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/PyIceberg - Getting Started.ipynb new file mode 100644 index 0000000000..b26adc3b3f --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/PyIceberg - Getting Started.ipynb @@ -0,0 +1,382 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1041ae6f", + "metadata": {}, + "source": [ + "![iceberg-logo](https://www.apache.org/logos/res/iceberg/iceberg.png)" + ] + }, + { + "cell_type": "markdown", + "id": "247fb2ab", + "metadata": {}, + "source": [ + "### [Docker, Spark, and Iceberg: The Fastest Way to Try Iceberg!](https://tabular.io/blog/docker-spark-and-iceberg/)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6a5c8206", + "metadata": {}, + "outputs": [], + "source": [ + "from pyiceberg import __version__\n", + "\n", + "__version__" + ] + }, + { + "cell_type": "markdown", + "id": "6f9a9f41", + "metadata": {}, + "source": [ + "## Load NYC Taxi/Limousine Trip Data\n", + "\n", + "For this notebook, we will use the New York City Taxi and Limousine Commision Trip Record Data that's available on the AWS Open Data Registry. This contains data of trips taken by taxis and for-hire vehicles in New York City. We'll save this into an iceberg table called `taxis`." + ] + }, + { + "cell_type": "markdown", + "id": "747bee98", + "metadata": {}, + "source": [ + "To be able to rerun the notebook several times, let's drop the table if it exists to start fresh." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "84fd09a4", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "CREATE DATABASE IF NOT EXISTS nyc;" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "07bf9dc2", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "DROP TABLE IF EXISTS nyc.taxis;" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "363f815a", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "CREATE TABLE IF NOT EXISTS nyc.taxis (\n", + " VendorID bigint,\n", + " tpep_pickup_datetime timestamp,\n", + " tpep_dropoff_datetime timestamp,\n", + " passenger_count double,\n", + " trip_distance double,\n", + " RatecodeID double,\n", + " store_and_fwd_flag string,\n", + " PULocationID bigint,\n", + " DOLocationID bigint,\n", + " payment_type bigint,\n", + " fare_amount double,\n", + " extra double,\n", + " mta_tax double,\n", + " tip_amount double,\n", + " tolls_amount double,\n", + " improvement_surcharge double,\n", + " total_amount double,\n", + " congestion_surcharge double,\n", + " airport_fee double\n", + ")\n", + "USING iceberg\n", + "PARTITIONED BY (days(tpep_pickup_datetime))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47645b52", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "\n", + "TRUNCATE TABLE nyc.taxis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9fddb808", + "metadata": {}, + "outputs": [], + "source": [ + "from pyspark.sql import SparkSession\n", + "spark = SparkSession.builder.appName(\"Jupyter\").getOrCreate()\n", + "\n", + "for filename in [\n", + " \"yellow_tripdata_2022-04.parquet\",\n", + " \"yellow_tripdata_2022-03.parquet\",\n", + " \"yellow_tripdata_2022-02.parquet\",\n", + " \"yellow_tripdata_2022-01.parquet\",\n", + " \"yellow_tripdata_2021-12.parquet\",\n", + "]:\n", + " df = spark.read.parquet(f\"/home/iceberg/data/{filename}\")\n", + " df.write.mode(\"append\").saveAsTable(\"nyc.taxis\")" + ] + }, + { + "cell_type": "markdown", + "id": "cffd2c03", + "metadata": {}, + "source": [ + "## Load data into a PyArrow Dataframe\n", + "\n", + "We'll fetch the table using the REST catalog that comes with the setup." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "efee8252", + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "from pyiceberg.catalog import load_catalog\n", + "from pyiceberg.expressions import GreaterThanOrEqual\n", + "\n", + "catalog = load_catalog('default')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "794de3a0", + "metadata": {}, + "outputs": [], + "source": [ + "tbl = catalog.load_table('nyc.taxis')\n", + "\n", + "sc = tbl.scan(row_filter=GreaterThanOrEqual(\"tpep_pickup_datetime\", \"2022-01-01T00:00:00.000000+00:00\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3ac7021", + "metadata": {}, + "outputs": [], + "source": [ + "df = sc.to_arrow().to_pandas()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5e818e4a", + "metadata": {}, + "outputs": [], + "source": [ + "len(df)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7034fa26", + "metadata": {}, + "outputs": [], + "source": [ + "df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "32d7e6ef", + "metadata": {}, + "outputs": [], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6fb4b02a", + "metadata": {}, + "outputs": [], + "source": [ + "df.hist(column='fare_amount')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "81f7cc19", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from scipy import stats\n", + "\n", + "stats.zscore(df['fare_amount'])\n", + "\n", + "# Remove everything larger than 3 stddev\n", + "df = df[(np.abs(stats.zscore(df['fare_amount'])) < 3)]\n", + "# Remove everything below zero\n", + "df = df[df['fare_amount'] > 0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18771ccb", + "metadata": {}, + "outputs": [], + "source": [ + "df.hist(column='fare_amount')" + ] + }, + { + "cell_type": "markdown", + "id": "886c8408", + "metadata": {}, + "source": [ + "# DuckDB\n", + "\n", + "Use DuckDB to Query the PyArrow Dataframe directly." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5d5d6fb8", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext sql\n", + "%config SqlMagic.autopandas = True\n", + "%config SqlMagic.feedback = False\n", + "%config SqlMagic.displaycon = False\n", + "%sql duckdb:///:memory:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4b6f9522", + "metadata": {}, + "outputs": [], + "source": [ + "%sql SELECT * FROM df LIMIT 20" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f5314f2b", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql --save tip-amount --no-execute\n", + "\n", + "SELECT tip_amount\n", + "FROM df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3dec260", + "metadata": {}, + "outputs": [], + "source": [ + "%sqlplot histogram --table df --column tip_amount --bins 22 --with tip-amount\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "989827d9", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql --save tip-amount-filtered --no-execute\n", + "\n", + "WITH tip_amount_stddev AS (\n", + " SELECT STDDEV_POP(tip_amount) AS tip_amount_stddev\n", + " FROM df\n", + ")\n", + "\n", + "SELECT tip_amount\n", + "FROM df, tip_amount_stddev\n", + "WHERE tip_amount > 0\n", + " AND tip_amount < tip_amount_stddev * 3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4d1df179", + "metadata": {}, + "outputs": [], + "source": [ + "%sqlplot histogram --table tip-amount-filtered --column tip_amount --bins 50 --with tip-amount-filtered\n" + ] + }, + { + "cell_type": "markdown", + "id": "08d2c62d", + "metadata": {}, + "source": [ + "# Iceberg ❤️ PyArrow and DuckDB\n", + "\n", + "This notebook shows how you can load data into a PyArrow dataframe and query it using DuckDB easily. Iceberg allows you to take a slice out of the data that you need for your analysis, while reducing the time that you have to wait for the data and without polluting the memory with data that you're not going to use." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "72a9c64d", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.16" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/PyIceberg - Write support.ipynb b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/PyIceberg - Write support.ipynb new file mode 100644 index 0000000000..e8b654fb40 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/notebooks/PyIceberg - Write support.ipynb @@ -0,0 +1,251 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1041ae6f", + "metadata": {}, + "source": [ + "![iceberg-logo](https://www.apache.org/logos/res/iceberg/iceberg.png)" + ] + }, + { + "cell_type": "markdown", + "id": "247fb2ab", + "metadata": {}, + "source": [ + "### [Docker, Spark, and Iceberg: The Fastest Way to Try Iceberg!](https://tabular.io/blog/docker-spark-and-iceberg/)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6a5c8206", + "metadata": {}, + "outputs": [], + "source": [ + "from pyiceberg import __version__\n", + "\n", + "__version__" + ] + }, + { + "cell_type": "markdown", + "id": "6f9a9f41", + "metadata": {}, + "source": [ + "# Write support\n", + "\n", + "This notebook demonstrates writing to Iceberg tables using PyIceberg. First, connect to the [catalog](https://iceberg.apache.org/concepts/catalog/#iceberg-catalogs), the place where tables are being tracked." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47645b52", + "metadata": {}, + "outputs": [], + "source": [ + "from pyiceberg.catalog import load_catalog\n", + "\n", + "catalog = load_catalog('default')" + ] + }, + { + "cell_type": "markdown", + "id": "c531bd4b-9943-4516-9a6a-99fab016ed2b", + "metadata": {}, + "source": [ + "# Loading data using Arrow\n", + "\n", + "PyArrow is used to load a Parquet file into memory, and using PyIceberg this data can be written to an Iceberg table." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9fddb808", + "metadata": {}, + "outputs": [], + "source": [ + "import pyarrow.parquet as pq\n", + "\n", + "df = pq.read_table(\"/home/iceberg/data/yellow_tripdata_2022-01.parquet\")\n", + "\n", + "df" + ] + }, + { + "cell_type": "markdown", + "id": "bf1d58ad-5cc1-4e8c-9d7b-a54e67def783", + "metadata": {}, + "source": [ + "# Create an Iceberg table\n", + "\n", + "Next create the Iceberg table directly from the `pyarrow.Table`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "47e5a21d-de87-4aaf-aa06-dc5048acba58", + "metadata": {}, + "outputs": [], + "source": [ + "table_name = \"default.taxi_dataset\"\n", + "\n", + "try:\n", + " # In case the table already exists\n", + " catalog.drop_table(table_name)\n", + "except:\n", + " pass\n", + "\n", + "table = catalog.create_table(table_name, schema=df.schema)\n", + "\n", + "table" + ] + }, + { + "cell_type": "markdown", + "id": "d612c035-4cf6-47a0-844b-165dfb463bbc", + "metadata": {}, + "source": [ + "# Write the data\n", + "\n", + "Let's append the data to the table. Appending or overwriting is equivalent since the table is empty. Next we can query the table and see that the data is there." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "efee8252", + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "table.append(df) # or table.overwrite(df)\n", + "\n", + "assert len(table.scan().to_arrow()) == len(df)\n", + "\n", + "table.scan().to_arrow()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9ce1cecc-8cb0-4622-b0eb-55880d091556", + "metadata": {}, + "outputs": [], + "source": [ + "str(table.current_snapshot())" + ] + }, + { + "cell_type": "markdown", + "id": "c029ea44-8ba6-4c08-a60d-5fffac6c3666", + "metadata": {}, + "source": [ + "# Append data\n", + "\n", + "Let's append another month of data to the table" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "794de3a0", + "metadata": {}, + "outputs": [], + "source": [ + "df = pq.read_table(\"/home/iceberg/data/yellow_tripdata_2022-02.parquet\")\n", + "table.append(df)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3ac7021", + "metadata": {}, + "outputs": [], + "source": [ + "str(table.current_snapshot())" + ] + }, + { + "cell_type": "markdown", + "id": "85862bdc-7476-43f4-a604-5e4dfff065c9", + "metadata": {}, + "source": [ + "# Feature generation\n", + "\n", + "Consider that we want to train a model to determine which features contribute to the tip amount. `tip_per_mile` is a good target to train the model on. When we try to append the data, we need to evolve the schema first." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "72a9c64d", + "metadata": {}, + "outputs": [], + "source": [ + "import pyarrow.compute as pc\n", + "\n", + "df = table.scan().to_arrow()\n", + "df = df.append_column(\"tip_per_mile\", pc.divide(df[\"tip_amount\"], df[\"trip_distance\"]))\n", + "\n", + "try:\n", + " table.overwrite(df)\n", + "except ValueError as e:\n", + " print(f\"Error: {e}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9aafd972-30d2-41ec-90e1-d5e17baeaf0b", + "metadata": {}, + "outputs": [], + "source": [ + "with table.update_schema() as upd:\n", + " upd.union_by_name(df.schema)\n", + "\n", + "print(str(table.schema()))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea4ee286-1943-4a88-8d96-1e2a9e11faa1", + "metadata": {}, + "outputs": [], + "source": [ + "table.overwrite(df)\n", + "\n", + "table" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.18" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/requirements.txt b/ccloud/custom-connector-connect-iceberg-sink/spark/requirements.txt new file mode 100644 index 0000000000..3272073f6f --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/requirements.txt @@ -0,0 +1,7 @@ +jupyter==1.0.0 +spylon-kernel==0.4.1 +pyiceberg[pyarrow,duckdb,pandas]==0.6.0 +jupysql==0.10.5 +matplotlib==3.8.4 +scipy==1.13.0 +duckdb-engine==0.11.5 diff --git a/ccloud/custom-connector-connect-iceberg-sink/spark/spark-defaults.conf b/ccloud/custom-connector-connect-iceberg-sink/spark/spark-defaults.conf new file mode 100755 index 0000000000..42b6c73f93 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/spark/spark-defaults.conf @@ -0,0 +1,33 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Default system properties included when running spark-submit. +# This is useful for setting default environmental settings. + +# Example: +spark.sql.extensions org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions +spark.sql.catalog.demo org.apache.iceberg.spark.SparkCatalog +spark.sql.catalog.demo.type rest +spark.sql.catalog.demo.uri http://rest:8181 +spark.sql.catalog.demo.io-impl org.apache.iceberg.aws.s3.S3FileIO +spark.sql.catalog.demo.warehouse s3://warehouse/wh/ +spark.sql.catalog.demo.s3.endpoint http://minio:9000 +spark.sql.defaultCatalog demo +spark.eventLog.enabled true +spark.eventLog.dir /home/iceberg/spark-events +spark.history.fs.logDirectory /home/iceberg/spark-events +spark.sql.catalogImplementation in-memory diff --git a/ccloud/custom-connector-connect-iceberg-sink/stop.sh b/ccloud/custom-connector-connect-iceberg-sink/stop.sh new file mode 100755 index 0000000000..7cd7cdca18 --- /dev/null +++ b/ccloud/custom-connector-connect-iceberg-sink/stop.sh @@ -0,0 +1,10 @@ +#!/bin/bash + + + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +docker compose down -v --remove-orphans + +maybe_delete_ccloud_environment \ No newline at end of file From 562dcdba406ee97be7f63a4aeb0041459a96a26e Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 16 Oct 2024 12:16:32 +0200 Subject: [PATCH 029/659] minor --- ccloud/custom-connector-connect-aws-s3-sink/stop.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100755 ccloud/custom-connector-connect-aws-s3-sink/stop.sh diff --git a/ccloud/custom-connector-connect-aws-s3-sink/stop.sh b/ccloud/custom-connector-connect-aws-s3-sink/stop.sh new file mode 100755 index 0000000000..7cd7cdca18 --- /dev/null +++ b/ccloud/custom-connector-connect-aws-s3-sink/stop.sh @@ -0,0 +1,10 @@ +#!/bin/bash + + + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +docker compose down -v --remove-orphans + +maybe_delete_ccloud_environment \ No newline at end of file From 363a9f9c2412f6b672b8e292cc2a2420d2d5b276 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 18 Oct 2024 10:16:52 +0200 Subject: [PATCH 030/659] topic produce: make nb_max_messages_to_generate configurable #5976 --- scripts/cli/completions.bash | 2 +- scripts/cli/playground | 540 +++++++++++++++------- scripts/cli/playground.json | 7 + scripts/cli/playground.yaml | 10 + scripts/cli/src/bashly.yml | 10 + scripts/cli/src/commands/topic/produce.sh | 19 +- 6 files changed, 410 insertions(+), 178 deletions(-) diff --git a/scripts/cli/completions.bash b/scripts/cli/completions.bash index 133d4a5e45..6a8a3652e1 100644 --- a/scripts/cli/completions.bash +++ b/scripts/cli/completions.bash @@ -1113,7 +1113,7 @@ _playground_completions() { ;; *'topic produce'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --max-nb-messages-to-generate --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") ;; *'topic alter'*'-t') diff --git a/scripts/cli/playground b/scripts/cli/playground index 3d10054809..f55c2e71ce 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# This script was generated by bashly 1.2.2 (https://bashly.dannyb.co) +# This script was generated by bashly 1.2.3 (https://bashly.dannyb.co) # Modifying it manually is not recommended # :wrapper.bash3_bouncer @@ -4486,6 +4486,11 @@ playground_topic_produce_usage() { printf " %s\n" "Default: 300000" echo + # :flag.usage + printf " %s\n" "$(magenta "--max-nb-messages-to-generate MAX-NB-MESSAGES-TO-GENERATE")" + printf " 🔨 Max number of different messages to generate.\n \n - when protobuf is used, default is 50 as protobuf generation is really\n slow\n - when --record-size is set, default is 100\n - otherwise default is 100000\n" + echo + # :flag.usage printf " %s\n" "$(magenta "--sleep-time-between-batch SLEEP-TIME-BETWEEN-BATCH")" printf " 💤 Sleep time in seconds between batches\n default is 0\n" @@ -20276,6 +20281,7 @@ playground_topic_produce_command() { validate="${args[--validate]}" record_size="${args[--record-size]}" max_nb_messages_per_batch="${args[--max-nb-messages-per-batch]}" + max_nb_messages_to_generate="${args[--max-nb-messages-to-generate]}" sleep_time_between_batch="${args[--sleep-time-between-batch]}" compression_codec="${args[--compression-codec]}" value_schema_id="${args[--value-schema-id]}" @@ -20629,15 +20635,22 @@ playground_topic_produce_command() { type="$4" input_file="" - if [ "$schema_type" == "protobuf" ] + if [[ -n "$max_nb_messages_to_generate" ]] then - nb_max_messages_to_generate=50 + log "🔨 --max-nb-messages-to-generate is set with $max_nb_messages_to_generate (it can be slow if number is high)" + nb_max_messages_to_generate=$max_nb_messages_to_generate else - if [ $record_size != 0 ] && [ "$type" == "VALUE" ] + + if [ "$schema_type" == "protobuf" ] then - nb_max_messages_to_generate=100 + nb_max_messages_to_generate=50 else - nb_max_messages_to_generate=500 + if [ "$record_size" != 0 ] && [ "$type" == "VALUE" ] + then + nb_max_messages_to_generate=100 + else + nb_max_messages_to_generate=100000 + fi fi fi if [ $nb_messages = -1 ] @@ -25192,7 +25205,8 @@ playground_ec2_sync_repro_folder_ec2_to_local_command() { parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --version) version_command exit @@ -25672,7 +25686,8 @@ parse_requirements() { playground_help_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_help_usage @@ -25722,7 +25737,8 @@ playground_help_parse_requirements() { playground_status_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_status_usage @@ -25766,7 +25782,8 @@ playground_status_parse_requirements() { playground_get_docker_ports_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_docker_ports_usage @@ -25810,7 +25827,8 @@ playground_get_docker_ports_parse_requirements() { playground_get_connector_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_connector_list_usage @@ -25854,7 +25872,8 @@ playground_get_connector_list_parse_requirements() { playground_get_ec2_instance_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_ec2_instance_list_usage @@ -25904,7 +25923,8 @@ playground_get_ec2_instance_list_parse_requirements() { playground_get_ec2_cloudformation_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_ec2_cloudformation_list_usage @@ -25954,7 +25974,8 @@ playground_get_ec2_cloudformation_list_parse_requirements() { playground_get_zazkia_connection_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_zazkia_connection_list_usage @@ -25998,7 +26019,8 @@ playground_get_zazkia_connection_list_parse_requirements() { playground_generate_fzf_find_files_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_generate_fzf_find_files_usage @@ -26042,7 +26064,8 @@ playground_generate_fzf_find_files_parse_requirements() { playground_generate_tag_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_generate_tag_list_usage @@ -26086,7 +26109,8 @@ playground_generate_tag_list_parse_requirements() { playground_generate_connector_plugin_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_generate_connector_plugin_list_usage @@ -26130,7 +26154,8 @@ playground_generate_connector_plugin_list_parse_requirements() { playground_generate_kafka_region_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_generate_kafka_region_list_usage @@ -26183,7 +26208,8 @@ playground_generate_kafka_region_list_parse_requirements() { playground_get_connector_plugin_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_connector_plugin_usage @@ -26233,7 +26259,8 @@ playground_get_connector_plugin_parse_requirements() { playground_get_ccloud_environment_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_ccloud_environment_list_usage @@ -26283,7 +26310,8 @@ playground_get_ccloud_environment_list_parse_requirements() { playground_get_ccloud_cluster_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_ccloud_cluster_list_usage @@ -26333,7 +26361,8 @@ playground_get_ccloud_cluster_list_parse_requirements() { playground_get_tag_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_tag_list_usage @@ -26383,7 +26412,8 @@ playground_get_tag_list_parse_requirements() { playground_get_kafka_region_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_kafka_region_list_usage @@ -26442,7 +26472,8 @@ playground_get_kafka_region_list_parse_requirements() { playground_get_topic_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_topic_list_usage @@ -26493,7 +26524,8 @@ playground_get_topic_list_parse_requirements() { playground_get_subject_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_subject_list_usage @@ -26544,7 +26576,8 @@ playground_get_subject_list_parse_requirements() { playground_get_examples_list_with_fzf_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_examples_list_with_fzf_usage @@ -26689,7 +26722,8 @@ playground_get_examples_list_with_fzf_parse_requirements() { playground_get_zip_or_jar_with_fzf_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_zip_or_jar_with_fzf_usage @@ -26758,7 +26792,8 @@ playground_get_zip_or_jar_with_fzf_parse_requirements() { playground_get_specific_file_extension_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_specific_file_extension_usage @@ -26821,7 +26856,8 @@ playground_get_specific_file_extension_parse_requirements() { playground_get_any_file_with_fzf_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_any_file_with_fzf_usage @@ -26871,7 +26907,8 @@ playground_get_any_file_with_fzf_parse_requirements() { playground_get_playground_repro_export_with_fzf_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_playground_repro_export_with_fzf_usage @@ -26921,7 +26958,8 @@ playground_get_playground_repro_export_with_fzf_parse_requirements() { playground_get_predefined_schemas_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_predefined_schemas_usage @@ -26971,7 +27009,8 @@ playground_get_predefined_schemas_parse_requirements() { playground_update_readme_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_update_readme_usage @@ -27047,7 +27086,8 @@ playground_update_readme_parse_requirements() { playground_bashly_reload_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_bashly_reload_usage @@ -27100,7 +27140,8 @@ playground_bashly_reload_parse_requirements() { playground_state_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_state_usage @@ -27188,7 +27229,8 @@ playground_state_parse_requirements() { playground_state_show_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_state_show_usage @@ -27232,7 +27274,8 @@ playground_state_show_parse_requirements() { playground_state_get_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_state_get_usage @@ -27293,7 +27336,8 @@ playground_state_get_parse_requirements() { playground_state_set_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_state_set_usage @@ -27367,7 +27411,8 @@ playground_state_set_parse_requirements() { playground_state_del_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_state_del_usage @@ -27428,7 +27473,8 @@ playground_state_del_parse_requirements() { playground_config_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_config_usage @@ -27551,7 +27597,8 @@ playground_config_parse_requirements() { playground_config_show_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_config_show_usage @@ -27595,7 +27642,8 @@ playground_config_show_parse_requirements() { playground_config_get_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_config_get_usage @@ -27656,7 +27704,8 @@ playground_config_get_parse_requirements() { playground_config_set_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_config_set_usage @@ -27730,7 +27779,8 @@ playground_config_set_parse_requirements() { playground_config_editor_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_config_editor_usage @@ -27798,7 +27848,8 @@ playground_config_editor_parse_requirements() { playground_config_folder_zip_or_jar_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_config_folder_zip_or_jar_usage @@ -27875,7 +27926,8 @@ playground_config_folder_zip_or_jar_parse_requirements() { playground_config_clipboard_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_config_clipboard_usage @@ -27928,7 +27980,8 @@ playground_config_clipboard_parse_requirements() { playground_config_open_ccloud_connector_in_browser_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_config_open_ccloud_connector_in_browser_usage @@ -28002,7 +28055,8 @@ playground_config_open_ccloud_connector_in_browser_parse_requirements() { playground_config_open_ccloud_connector_in_browser_automatically_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_config_open_ccloud_connector_in_browser_automatically_usage @@ -28055,7 +28109,8 @@ playground_config_open_ccloud_connector_in_browser_automatically_parse_requireme playground_config_open_ccloud_connector_in_browser_browser_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_config_open_ccloud_connector_in_browser_browser_usage @@ -28108,7 +28163,8 @@ playground_config_open_ccloud_connector_in_browser_browser_parse_requirements() playground_config_container_kill_all_before_run_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_config_container_kill_all_before_run_usage @@ -28161,7 +28217,8 @@ playground_config_container_kill_all_before_run_parse_requirements() { playground_config_check_repo_version_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_config_check_repo_version_usage @@ -28214,7 +28271,8 @@ playground_config_check_repo_version_parse_requirements() { playground_run_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_run_usage @@ -28614,7 +28672,8 @@ playground_run_parse_requirements() { playground_re_run_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_re_run_usage @@ -28667,7 +28726,8 @@ playground_re_run_parse_requirements() { playground_history_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_history_usage @@ -28720,7 +28780,8 @@ playground_history_parse_requirements() { playground_start_environment_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_start_environment_usage @@ -28815,7 +28876,8 @@ playground_start_environment_parse_requirements() { playground_switch_ccloud_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_switch_ccloud_usage @@ -28868,7 +28930,8 @@ playground_switch_ccloud_parse_requirements() { playground_switch_back_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_switch_back_usage @@ -28912,7 +28975,8 @@ playground_switch_back_parse_requirements() { playground_update_version_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_update_version_usage @@ -29034,7 +29098,8 @@ playground_update_version_parse_requirements() { playground_open_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_open_usage @@ -29107,7 +29172,8 @@ playground_open_parse_requirements() { playground_stop_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_stop_usage @@ -29151,7 +29217,8 @@ playground_stop_parse_requirements() { playground_remove_all_docker_images_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_remove_all_docker_images_usage @@ -29195,7 +29262,8 @@ playground_remove_all_docker_images_parse_requirements() { playground_cleanup_cloud_details_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_cleanup_cloud_details_usage @@ -29239,7 +29307,8 @@ playground_cleanup_cloud_details_parse_requirements() { playground_open_docs_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_open_docs_usage @@ -29290,7 +29359,8 @@ playground_open_docs_parse_requirements() { playground_cleanup_cloud_resources_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_cleanup_cloud_resources_usage @@ -29406,7 +29476,8 @@ playground_cleanup_cloud_resources_parse_requirements() { playground_repro_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_repro_usage @@ -29502,7 +29573,8 @@ playground_repro_parse_requirements() { playground_repro_export_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_repro_export_usage @@ -29562,7 +29634,8 @@ playground_repro_export_parse_requirements() { playground_repro_import_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_repro_import_usage @@ -29626,7 +29699,8 @@ playground_repro_import_parse_requirements() { playground_repro_bootstrap_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_repro_bootstrap_usage @@ -29812,7 +29886,8 @@ playground_repro_bootstrap_parse_requirements() { playground_get_docker_compose_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_docker_compose_usage @@ -29856,7 +29931,8 @@ playground_get_docker_compose_parse_requirements() { playground_schema_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_schema_usage @@ -29965,7 +30041,8 @@ playground_schema_parse_requirements() { playground_schema_get_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_schema_get_usage @@ -30089,7 +30166,8 @@ playground_schema_get_parse_requirements() { playground_schema_register_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_schema_register_usage @@ -30211,7 +30289,8 @@ playground_schema_register_parse_requirements() { playground_schema_get_compatibility_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_schema_get_compatibility_usage @@ -30295,7 +30374,8 @@ playground_schema_get_compatibility_parse_requirements() { playground_schema_set_compatibility_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_schema_set_compatibility_usage @@ -30403,7 +30483,8 @@ playground_schema_set_compatibility_parse_requirements() { playground_schema_get_mode_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_schema_get_mode_usage @@ -30487,7 +30568,8 @@ playground_schema_get_mode_parse_requirements() { playground_schema_set_mode_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_schema_set_mode_usage @@ -30595,7 +30677,8 @@ playground_schema_set_mode_parse_requirements() { playground_schema_delete_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_schema_delete_usage @@ -30732,7 +30815,8 @@ playground_schema_delete_parse_requirements() { playground_tcp_proxy_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tcp_proxy_usage @@ -30869,7 +30953,8 @@ playground_tcp_proxy_parse_requirements() { playground_tcp_proxy_start_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tcp_proxy_start_usage @@ -31038,7 +31123,8 @@ playground_tcp_proxy_start_parse_requirements() { playground_tcp_proxy_get_connections_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tcp_proxy_get_connections_usage @@ -31102,7 +31188,8 @@ playground_tcp_proxy_get_connections_parse_requirements() { playground_tcp_proxy_delay_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tcp_proxy_delay_usage @@ -31192,7 +31279,8 @@ playground_tcp_proxy_delay_parse_requirements() { playground_tcp_proxy_break_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tcp_proxy_break_usage @@ -31282,7 +31370,8 @@ playground_tcp_proxy_break_parse_requirements() { playground_tcp_proxy_close_connection_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tcp_proxy_close_connection_usage @@ -31346,7 +31435,8 @@ playground_tcp_proxy_close_connection_parse_requirements() { playground_tcp_proxy_close_all_connection_with_error_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tcp_proxy_close_all_connection_with_error_usage @@ -31390,7 +31480,8 @@ playground_tcp_proxy_close_all_connection_with_error_parse_requirements() { playground_tcp_proxy_toggle_accept_connections_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tcp_proxy_toggle_accept_connections_usage @@ -31434,7 +31525,8 @@ playground_tcp_proxy_toggle_accept_connections_parse_requirements() { playground_tcp_proxy_toggle_reads_client_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tcp_proxy_toggle_reads_client_usage @@ -31498,7 +31590,8 @@ playground_tcp_proxy_toggle_reads_client_parse_requirements() { playground_tcp_proxy_toggle_reads_service_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tcp_proxy_toggle_reads_service_usage @@ -31562,7 +31655,8 @@ playground_tcp_proxy_toggle_reads_service_parse_requirements() { playground_tcp_proxy_toggle_writes_client_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tcp_proxy_toggle_writes_client_usage @@ -31626,7 +31720,8 @@ playground_tcp_proxy_toggle_writes_client_parse_requirements() { playground_tcp_proxy_toggle_writes_service_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tcp_proxy_toggle_writes_service_usage @@ -31690,7 +31785,8 @@ playground_tcp_proxy_toggle_writes_service_parse_requirements() { playground_tools_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tools_usage @@ -31771,7 +31867,8 @@ playground_tools_parse_requirements() { playground_tools_install_vscode_extension_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tools_install_vscode_extension_usage @@ -31824,7 +31921,8 @@ playground_tools_install_vscode_extension_parse_requirements() { playground_tools_read_avro_file_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tools_read_avro_file_usage @@ -31888,7 +31986,8 @@ playground_tools_read_avro_file_parse_requirements() { playground_tools_read_parquet_file_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_tools_read_parquet_file_usage @@ -31952,7 +32051,8 @@ playground_tools_read_parquet_file_parse_requirements() { playground_debug_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_debug_usage @@ -32082,7 +32182,8 @@ playground_debug_parse_requirements() { playground_debug_enable_remote_debugging_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_debug_enable_remote_debugging_usage @@ -32142,7 +32243,8 @@ playground_debug_enable_remote_debugging_parse_requirements() { playground_debug_testssl_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_debug_testssl_usage @@ -32192,7 +32294,8 @@ playground_debug_testssl_parse_requirements() { playground_debug_generate_diagnostics_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_debug_generate_diagnostics_usage @@ -32252,7 +32355,8 @@ playground_debug_generate_diagnostics_parse_requirements() { playground_debug_thread_dump_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_debug_thread_dump_usage @@ -32312,7 +32416,8 @@ playground_debug_thread_dump_parse_requirements() { playground_debug_heap_dump_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_debug_heap_dump_usage @@ -32388,7 +32493,8 @@ playground_debug_heap_dump_parse_requirements() { playground_debug_tcp_dump_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_debug_tcp_dump_usage @@ -32490,7 +32596,8 @@ playground_debug_tcp_dump_parse_requirements() { playground_debug_block_traffic_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_debug_block_traffic_usage @@ -32615,7 +32722,8 @@ playground_debug_block_traffic_parse_requirements() { playground_debug_java_debug_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_debug_java_debug_usage @@ -32720,7 +32828,8 @@ playground_debug_java_debug_parse_requirements() { playground_debug_flight_recorder_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_debug_flight_recorder_usage @@ -32806,7 +32915,8 @@ playground_debug_flight_recorder_parse_requirements() { playground_debug_log_level_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_debug_log_level_usage @@ -32887,7 +32997,8 @@ playground_debug_log_level_parse_requirements() { playground_debug_log_level_get_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_debug_log_level_get_usage @@ -32951,7 +33062,8 @@ playground_debug_log_level_get_parse_requirements() { playground_debug_log_level_set_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_debug_log_level_set_usage @@ -33045,7 +33157,8 @@ playground_debug_log_level_set_parse_requirements() { playground_get_jmx_metrics_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_get_jmx_metrics_usage @@ -33136,7 +33249,8 @@ playground_get_jmx_metrics_parse_requirements() { playground_container_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_container_usage @@ -33287,7 +33401,8 @@ playground_container_parse_requirements() { playground_container_get_properties_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_container_get_properties_usage @@ -33347,7 +33462,8 @@ playground_container_get_properties_parse_requirements() { playground_container_recreate_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_container_recreate_usage @@ -33398,7 +33514,8 @@ playground_container_recreate_parse_requirements() { playground_container_get_ip_addresses_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_container_get_ip_addresses_usage @@ -33442,7 +33559,8 @@ playground_container_get_ip_addresses_parse_requirements() { playground_container_kill_all_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_container_kill_all_usage @@ -33486,7 +33604,8 @@ playground_container_kill_all_parse_requirements() { playground_container_logs_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_container_logs_usage @@ -33611,7 +33730,8 @@ playground_container_logs_parse_requirements() { playground_container_ssh_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_container_ssh_usage @@ -33692,7 +33812,8 @@ playground_container_ssh_parse_requirements() { playground_container_change_jdk_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_container_change_jdk_usage @@ -33778,7 +33899,8 @@ playground_container_change_jdk_parse_requirements() { playground_container_exec_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_container_exec_usage @@ -33894,7 +34016,8 @@ playground_container_exec_parse_requirements() { playground_container_restart_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_container_restart_usage @@ -33954,7 +34077,8 @@ playground_container_restart_parse_requirements() { playground_container_pause_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_container_pause_usage @@ -34014,7 +34138,8 @@ playground_container_pause_parse_requirements() { playground_container_resume_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_container_resume_usage @@ -34074,7 +34199,8 @@ playground_container_resume_parse_requirements() { playground_container_kill_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_container_kill_usage @@ -34134,7 +34260,8 @@ playground_container_kill_parse_requirements() { playground_container_set_environment_variables_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_container_set_environment_variables_usage @@ -34231,7 +34358,8 @@ playground_container_set_environment_variables_parse_requirements() { playground_topic_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_topic_usage @@ -34368,7 +34496,8 @@ playground_topic_parse_requirements() { playground_topic_get_number_records_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_topic_get_number_records_usage @@ -34425,7 +34554,8 @@ playground_topic_get_number_records_parse_requirements() { playground_topic_display_consumer_offsets_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_topic_display_consumer_offsets_usage @@ -34476,7 +34606,8 @@ playground_topic_display_consumer_offsets_parse_requirements() { playground_topic_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_topic_list_usage @@ -34520,7 +34651,8 @@ playground_topic_list_parse_requirements() { playground_topic_describe_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_topic_describe_usage @@ -34585,7 +34717,8 @@ playground_topic_describe_parse_requirements() { playground_topic_set_schema_compatibility_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_topic_set_schema_compatibility_usage @@ -34683,7 +34816,8 @@ playground_topic_set_schema_compatibility_parse_requirements() { playground_topic_consume_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_topic_consume_usage @@ -34914,7 +35048,8 @@ playground_topic_consume_parse_requirements() { playground_topic_produce_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_topic_produce_usage @@ -35021,6 +35156,20 @@ playground_topic_produce_parse_requirements() { fi ;; + # :flag.case + --max-nb-messages-to-generate) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + args['--max-nb-messages-to-generate']="$2" + shift + shift + else + printf "%s\n" "--max-nb-messages-to-generate requires an argument: --max-nb-messages-to-generate MAX-NB-MESSAGES-TO-GENERATE" >&2 + exit 1 + fi + ;; + # :flag.case --sleep-time-between-batch) @@ -35323,6 +35472,12 @@ playground_topic_produce_parse_requirements() { exit 1 fi + # :flag.validations + if [[ -v args['--max-nb-messages-to-generate'] && -n $(validate_integer "${args['--max-nb-messages-to-generate']:-}") ]]; then + printf "validation error in %s:\n%s\n" "--max-nb-messages-to-generate MAX-NB-MESSAGES-TO-GENERATE" "$(validate_integer "${args['--max-nb-messages-to-generate']:-}")" >&2 + exit 1 + fi + # :flag.validations if [[ -v args['--sleep-time-between-batch'] && -n $(validate_integer "${args['--sleep-time-between-batch']:-}") ]]; then printf "validation error in %s:\n%s\n" "--sleep-time-between-batch SLEEP-TIME-BETWEEN-BATCH" "$(validate_integer "${args['--sleep-time-between-batch']:-}")" >&2 @@ -35386,7 +35541,8 @@ playground_topic_produce_parse_requirements() { playground_topic_create_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_topic_create_usage @@ -35487,7 +35643,8 @@ playground_topic_create_parse_requirements() { playground_topic_delete_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_topic_delete_usage @@ -35566,7 +35723,8 @@ playground_topic_delete_parse_requirements() { playground_topic_alter_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_topic_alter_usage @@ -35643,7 +35801,8 @@ playground_topic_alter_parse_requirements() { playground_connector_plugin_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_plugin_usage @@ -35717,7 +35876,8 @@ playground_connector_plugin_parse_requirements() { playground_connector_plugin_search_jar_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_plugin_search_jar_usage @@ -35822,7 +35982,8 @@ playground_connector_plugin_search_jar_parse_requirements() { playground_connector_plugin_versions_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_plugin_versions_usage @@ -35919,7 +36080,8 @@ playground_connector_plugin_versions_parse_requirements() { playground_connector_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_usage @@ -36126,7 +36288,8 @@ playground_connector_parse_requirements() { playground_connector_status_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_status_usage @@ -36191,7 +36354,8 @@ playground_connector_status_parse_requirements() { playground_connector_offsets_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_offsets_usage @@ -36279,7 +36443,8 @@ playground_connector_offsets_parse_requirements() { playground_connector_offsets_get_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_offsets_get_usage @@ -36344,7 +36509,8 @@ playground_connector_offsets_get_parse_requirements() { playground_connector_offsets_reset_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_offsets_reset_usage @@ -36409,7 +36575,8 @@ playground_connector_offsets_reset_parse_requirements() { playground_connector_offsets_alter_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_offsets_alter_usage @@ -36474,7 +36641,8 @@ playground_connector_offsets_alter_parse_requirements() { playground_connector_offsets_get_offsets_request_status_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_offsets_get_offsets_request_status_usage @@ -36539,7 +36707,8 @@ playground_connector_offsets_get_offsets_request_status_parse_requirements() { playground_connector_plugins_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_plugins_usage @@ -36598,7 +36767,8 @@ playground_connector_plugins_parse_requirements() { playground_connector_pause_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_pause_usage @@ -36663,7 +36833,8 @@ playground_connector_pause_parse_requirements() { playground_connector_versions_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_versions_usage @@ -36707,7 +36878,8 @@ playground_connector_versions_parse_requirements() { playground_connector_restart_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_restart_usage @@ -36772,7 +36944,8 @@ playground_connector_restart_parse_requirements() { playground_connector_stop_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_stop_usage @@ -36837,7 +37010,8 @@ playground_connector_stop_parse_requirements() { playground_connector_resume_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_resume_usage @@ -36902,7 +37076,8 @@ playground_connector_resume_parse_requirements() { playground_connector_delete_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_delete_usage @@ -36967,7 +37142,8 @@ playground_connector_delete_parse_requirements() { playground_connector_show_lag_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_show_lag_usage @@ -37077,7 +37253,8 @@ playground_connector_show_lag_parse_requirements() { playground_connector_show_config_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_show_config_usage @@ -37158,7 +37335,8 @@ playground_connector_show_config_parse_requirements() { playground_connector_show_config_parameters_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_show_config_parameters_usage @@ -37263,7 +37441,8 @@ playground_connector_show_config_parameters_parse_requirements() { playground_connector_select_config_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_select_config_usage @@ -37329,7 +37508,8 @@ playground_connector_select_config_parse_requirements() { playground_connector_snippets_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_snippets_usage @@ -37400,7 +37580,8 @@ playground_connector_snippets_parse_requirements() { playground_connector_open_docs_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_open_docs_usage @@ -37451,7 +37632,8 @@ playground_connector_open_docs_parse_requirements() { playground_connector_log_level_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_log_level_usage @@ -37534,7 +37716,8 @@ playground_connector_log_level_parse_requirements() { playground_connector_logs_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_logs_usage @@ -37658,7 +37841,8 @@ playground_connector_logs_parse_requirements() { playground_connector_open_ccloud_connector_in_browser_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_open_ccloud_connector_in_browser_usage @@ -37729,7 +37913,8 @@ playground_connector_open_ccloud_connector_in_browser_parse_requirements() { playground_connector_create_or_update_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_create_or_update_usage @@ -37920,7 +38105,8 @@ playground_connector_create_or_update_parse_requirements() { playground_connector_update_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_connector_update_usage @@ -37977,7 +38163,8 @@ playground_connector_update_parse_requirements() { playground_ec2_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_ec2_usage @@ -38107,7 +38294,8 @@ playground_ec2_parse_requirements() { playground_ec2_create_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_ec2_create_usage @@ -38209,7 +38397,8 @@ playground_ec2_create_parse_requirements() { playground_ec2_delete_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_ec2_delete_usage @@ -38273,7 +38462,8 @@ playground_ec2_delete_parse_requirements() { playground_ec2_open_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_ec2_open_usage @@ -38345,7 +38535,8 @@ playground_ec2_open_parse_requirements() { playground_ec2_allow_my_ip_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_ec2_allow_my_ip_usage @@ -38409,7 +38600,8 @@ playground_ec2_allow_my_ip_parse_requirements() { playground_ec2_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_ec2_list_usage @@ -38453,7 +38645,8 @@ playground_ec2_list_parse_requirements() { playground_ec2_stop_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_ec2_stop_usage @@ -38517,7 +38710,8 @@ playground_ec2_stop_parse_requirements() { playground_ec2_start_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_ec2_start_usage @@ -38581,7 +38775,8 @@ playground_ec2_start_parse_requirements() { playground_ec2_status_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_ec2_status_usage @@ -38659,7 +38854,8 @@ playground_ec2_status_parse_requirements() { playground_ec2_sync_repro_folder_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_ec2_sync_repro_folder_usage @@ -38742,7 +38938,8 @@ playground_ec2_sync_repro_folder_parse_requirements() { playground_ec2_sync_repro_folder_local_to_ec2_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_ec2_sync_repro_folder_local_to_ec2_usage @@ -38806,7 +39003,8 @@ playground_ec2_sync_repro_folder_local_to_ec2_parse_requirements() { playground_ec2_sync_repro_folder_ec2_to_local_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do - case "${1:-}" in + key="$1" + case "$key" in --help | -h) long_usage=yes playground_ec2_sync_repro_folder_ec2_to_local_usage diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index ec8e9af675..7b61e2e0a1 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -1835,6 +1835,13 @@ "argument": 300000, "description": "🔼 Max number of messages to send per batch when --nb-messages > --max-nb-messages-per-batch\n if --nb-messages is set to -1, this is the number of messages sent per batch\n default is 300000\n\nDefault value: 300000\n" }, + { + "names": [ + "--max-nb-messages-to-generate" + ], + "argument": "MAX-NB-MESSAGES-TO-GENERATE", + "description": "🔨 Max number of different messages to generate.\n\n - when protobuf is used, default is 50 as protobuf generation is really slow\n - when --record-size is set, default is 100\n - otherwise default is 100000\n" + }, { "names": [ "--sleep-time-between-batch" diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index 47c870ecb7..7803efbb01 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -1995,6 +1995,16 @@ subcommands: Default value: 300000 + - names: + - --max-nb-messages-to-generate + argument: MAX-NB-MESSAGES-TO-GENERATE + description: | + 🔨 Max number of different messages to generate. + + - when protobuf is used, default is 50 as protobuf generation is really slow + - when --record-size is set, default is 100 + - otherwise default is 100000 + - names: - --sleep-time-between-batch argument: 0 diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index 9cb40ef299..c2084c9832 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -2256,6 +2256,16 @@ commands: 🔼 Max number of messages to send per batch when --nb-messages > --max-nb-messages-per-batch if --nb-messages is set to -1, this is the number of messages sent per batch default is 300000 + - long: --max-nb-messages-to-generate + arg: max-nb-messages-to-generate + validate: integer + required: false + help: |- + 🔨 Max number of different messages to generate. + + - when protobuf is used, default is 50 as protobuf generation is really slow + - when --record-size is set, default is 100 + - otherwise default is 100000 - long: --sleep-time-between-batch arg: sleep-time-between-batch validate: integer diff --git a/scripts/cli/src/commands/topic/produce.sh b/scripts/cli/src/commands/topic/produce.sh index 410b8f4512..662ebb3bef 100644 --- a/scripts/cli/src/commands/topic/produce.sh +++ b/scripts/cli/src/commands/topic/produce.sh @@ -16,6 +16,7 @@ value_subject_name_strategy="${args[--value-subject-name-strategy]}" validate="${args[--validate]}" record_size="${args[--record-size]}" max_nb_messages_per_batch="${args[--max-nb-messages-per-batch]}" +max_nb_messages_to_generate="${args[--max-nb-messages-to-generate]}" sleep_time_between_batch="${args[--sleep-time-between-batch]}" compression_codec="${args[--compression-codec]}" value_schema_id="${args[--value-schema-id]}" @@ -366,15 +367,21 @@ function generate_data() { type="$4" input_file="" - if [ "$schema_type" == "protobuf" ] + if [[ -n "$max_nb_messages_to_generate" ]] then - nb_max_messages_to_generate=50 - else - if [ $record_size != 0 ] && [ "$type" == "VALUE" ] + log "🔨 --max-nb-messages-to-generate is set with $max_nb_messages_to_generate (it can be slow if number is high)" + nb_max_messages_to_generate=$max_nb_messages_to_generate + else + if [ "$schema_type" == "protobuf" ] then - nb_max_messages_to_generate=100 + nb_max_messages_to_generate=50 else - nb_max_messages_to_generate=500 + if [ "$record_size" != 0 ] && [ "$type" == "VALUE" ] + then + nb_max_messages_to_generate=100 + else + nb_max_messages_to_generate=100000 + fi fi fi if [ $nb_messages = -1 ] From 72d5e0a7397fef5bd2b0fb0f9caec8b10099535b Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 21 Oct 2024 10:15:57 +0200 Subject: [PATCH 031/659] fix on linux --- connect/connect-ftps-sink/ftps-sink.sh | 4 ++-- connect/connect-ftps-source/ftps-source.sh | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/connect/connect-ftps-sink/ftps-sink.sh b/connect/connect-ftps-sink/ftps-sink.sh index cc8107fb51..df61775957 100755 --- a/connect/connect-ftps-sink/ftps-sink.sh +++ b/connect/connect-ftps-sink/ftps-sink.sh @@ -9,9 +9,9 @@ log "🔐 Generate keys and certificates used for SSL" docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/" cd ${DIR} -if [ ! -z "$GITHUB_RUN_NUMBER" ] +if [[ "$(uname)" != "Darwin" ]] then - # running with github actions + # Linux sudo chown root ${DIR}/config/vsftpd.conf sudo chown root ${DIR}/security/vsftpd.pem fi diff --git a/connect/connect-ftps-source/ftps-source.sh b/connect/connect-ftps-source/ftps-source.sh index 8dc37e18b6..e4b4b58477 100755 --- a/connect/connect-ftps-source/ftps-source.sh +++ b/connect/connect-ftps-source/ftps-source.sh @@ -9,9 +9,10 @@ log "🔐 Generate keys and certificates used for SSL" docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/" cd ${DIR} -if [ ! -z "$GITHUB_RUN_NUMBER" ] + +if [[ "$(uname)" != "Darwin" ]] then - # running with github actions + # Linux sudo chown root ${DIR}/config/vsftpd.conf sudo chown root ${DIR}/security/vsftpd.pem fi From b22f797550ac65afa6c26bf0628196df3331b291 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 22 Oct 2024 14:56:58 +0200 Subject: [PATCH 032/659] fix --- connect/connect-debezium-mysql-source/debezium-mysql-source.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connect/connect-debezium-mysql-source/debezium-mysql-source.sh b/connect/connect-debezium-mysql-source/debezium-mysql-source.sh index f572f1dd69..74f39e28f4 100755 --- a/connect/connect-debezium-mysql-source/debezium-mysql-source.sh +++ b/connect/connect-debezium-mysql-source/debezium-mysql-source.sh @@ -118,6 +118,6 @@ if [ ! -z "$SQL_DATAGEN" ] then DURATION=10 log "Injecting data for $DURATION minutes" - docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --connectionUrl 'jdbc:mysql://mysql:3306/mydb?user=user&password=password&useSSL=false' --maxPoolSize 10 --durationTimeMin $DURATION" + docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --connectionUrl 'jdbc:mysql://mysql:3306/mydb?user=debezium&password=dbz&useSSL=false&allowPublicKeyRetrieval=true' --maxPoolSize 10 --durationTimeMin $DURATION" fi From 05c022b14f89a42c05a562d6eab772a3965f0ec4 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 22 Oct 2024 15:22:20 +0200 Subject: [PATCH 033/659] fix --- .../fully-managed-debezium-legacy-mysql.sh | 2 +- .../fully-managed-debezium-v2-mysql.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh b/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh index 418d7a7ab7..8d17f9268a 100755 --- a/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh +++ b/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh @@ -149,7 +149,7 @@ if [ ! -z "$SQL_DATAGEN" ] then DURATION=10 log "Injecting data for $DURATION minutes" - docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --connectionUrl 'jdbc:mysql://mysql:3306/mydb?user=user&password=password&useSSL=false' --maxPoolSize 10 --durationTimeMin $DURATION" + docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --connectionUrl 'jdbc:mysql://mysql:3306/mydb?user=debezium&password=dbz&useSSL=false&allowPublicKeyRetrieval=true' --maxPoolSize 10 --durationTimeMin $DURATION fi log "Do you want to delete the fully managed connector $connector_name ?" diff --git a/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh b/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh index 45a031dc9b..7a4cf82ac2 100755 --- a/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh +++ b/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh @@ -148,7 +148,7 @@ if [ ! -z "$SQL_DATAGEN" ] then DURATION=10 log "Injecting data for $DURATION minutes" - docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --connectionUrl 'jdbc:mysql://mysql:3306/mydb?user=user&password=password&useSSL=false' --maxPoolSize 10 --durationTimeMin $DURATION" + docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --connectionUrl 'jdbc:mysql://mysql:3306/mydb?user=debezium&password=dbz&useSSL=false&allowPublicKeyRetrieval=true' --maxPoolSize 10 --durationTimeMin $DURATION fi log "Do you want to delete the fully managed connector $connector_name ?" From 0251bd014cb83c9541849e3fc67b3efb872b5669 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 22 Oct 2024 15:22:59 +0200 Subject: [PATCH 034/659] fix --- .../fully-managed-debezium-legacy-mysql.sh | 2 +- .../fully-managed-debezium-v2-mysql.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh b/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh index 8d17f9268a..b275a07f8b 100755 --- a/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh +++ b/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh @@ -149,7 +149,7 @@ if [ ! -z "$SQL_DATAGEN" ] then DURATION=10 log "Injecting data for $DURATION minutes" - docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --connectionUrl 'jdbc:mysql://mysql:3306/mydb?user=debezium&password=dbz&useSSL=false&allowPublicKeyRetrieval=true' --maxPoolSize 10 --durationTimeMin $DURATION + docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --connectionUrl 'jdbc:mysql://mysql:3306/mydb?user=debezium&password=dbz&useSSL=false&allowPublicKeyRetrieval=true' --maxPoolSize 10 --durationTimeMin $DURATION" fi log "Do you want to delete the fully managed connector $connector_name ?" diff --git a/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh b/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh index 7a4cf82ac2..d4d34617f0 100755 --- a/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh +++ b/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh @@ -148,7 +148,7 @@ if [ ! -z "$SQL_DATAGEN" ] then DURATION=10 log "Injecting data for $DURATION minutes" - docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --connectionUrl 'jdbc:mysql://mysql:3306/mydb?user=debezium&password=dbz&useSSL=false&allowPublicKeyRetrieval=true' --maxPoolSize 10 --durationTimeMin $DURATION + docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --connectionUrl 'jdbc:mysql://mysql:3306/mydb?user=debezium&password=dbz&useSSL=false&allowPublicKeyRetrieval=true' --maxPoolSize 10 --durationTimeMin $DURATION" fi log "Do you want to delete the fully managed connector $connector_name ?" From 4b2400ea8948dfbb364f7e03e0a761d407dba199 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 23 Oct 2024 10:35:20 +0200 Subject: [PATCH 035/659] fix --- .../fully-managed-debezium-legacy-mysql.sh | 4 ++-- .../fully-managed-debezium-v2-mysql.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh b/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh index b275a07f8b..975c3a71db 100755 --- a/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh +++ b/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh @@ -32,7 +32,7 @@ display_ngrok_warning bootstrap_ccloud_environment - +set_profiles set +e playground topic delete --topic dbserver1.mydb.team @@ -40,7 +40,7 @@ set -e docker compose build docker compose down -v --remove-orphans -docker compose up -d --quiet-pull +docker compose ${profile_sql_datagen_command} up -d --quiet-pull sleep 30 diff --git a/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh b/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh index d4d34617f0..8d856005b9 100755 --- a/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh +++ b/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh @@ -32,7 +32,7 @@ display_ngrok_warning bootstrap_ccloud_environment - +set_profiles set +e playground topic delete --topic dbserver1.mydb.team @@ -40,7 +40,7 @@ set -e docker compose build docker compose down -v --remove-orphans -docker compose up -d --quiet-pull +docker compose ${profile_sql_datagen_command} up -d --quiet-pull sleep 30 From bb1be94b4f0b157dbf031953e2476f1ab8d39a2e Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 23 Oct 2024 10:35:29 +0200 Subject: [PATCH 036/659] update --- secrets.tar.gpg | Bin 7455 -> 7452 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/secrets.tar.gpg b/secrets.tar.gpg index 7028c9f3dc57006d058be0cd6e17d6f207ab1a36..df1f7152ae2202fb1acb955afd3d64d6ff39b8f5 100644 GIT binary patch literal 7452 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 aBr}vW_~xK%lP3e;f>L_AQy&4HI<@4uT6Wd| literal 7455 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 From 932e1ad5d906b3431ccd888bcb6b5ab9c4087113 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 25 Oct 2024 11:42:50 +0200 Subject: [PATCH 037/659] fix --- .../jdbc-snowflake-source.sh | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh b/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh index b3ef407618..d7a0163f4c 100755 --- a/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh +++ b/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh @@ -83,6 +83,7 @@ log "Create a Snowflake DB" docker run --quiet --rm -i -e SNOWSQL_PWD="$SNOWFLAKE_PASSWORD" -e RSA_PUBLIC_KEY="$RSA_PUBLIC_KEY" kurron/snowsql --username $SNOWFLAKE_USERNAME -a $SNOWFLAKE_ACCOUNT_NAME << EOF DROP DATABASE IF EXISTS $PLAYGROUND_DB; CREATE OR REPLACE DATABASE $PLAYGROUND_DB COMMENT = 'Database for Docker Playground'; +CREATE SCHEMA MYSCHEMA; EOF log "Create a Snowflake ROLE" @@ -92,12 +93,14 @@ DROP ROLE IF EXISTS $PLAYGROUND_CONNECTOR_ROLE; CREATE ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT USAGE ON DATABASE $PLAYGROUND_DB TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT USAGE ON DATABASE $PLAYGROUND_DB TO ACCOUNTADMIN; -GRANT USAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; -GRANT ALL ON FUTURE TABLES IN SCHEMA $PLAYGROUND_DB.PUBLIC TO $PLAYGROUND_CONNECTOR_ROLE; -GRANT USAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE ACCOUNTADMIN; -GRANT CREATE TABLE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; -GRANT CREATE STAGE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; -GRANT CREATE PIPE ON SCHEMA $PLAYGROUND_DB.PUBLIC TO ROLE $PLAYGROUND_CONNECTOR_ROLE; +GRANT USAGE ON SCHEMA $PLAYGROUND_DB.MYSCHEMA TO ROLE $PLAYGROUND_CONNECTOR_ROLE; +GRANT ALL ON FUTURE TABLES IN SCHEMA $PLAYGROUND_DB.MYSCHEMA TO $PLAYGROUND_CONNECTOR_ROLE; +GRANT USAGE ON SCHEMA $PLAYGROUND_DB.MYSCHEMA TO ROLE ACCOUNTADMIN; +GRANT CREATE TABLE ON SCHEMA $PLAYGROUND_DB.MYSCHEMA TO ROLE $PLAYGROUND_CONNECTOR_ROLE; +GRANT CREATE STAGE ON SCHEMA $PLAYGROUND_DB.MYSCHEMA TO ROLE $PLAYGROUND_CONNECTOR_ROLE; +GRANT CREATE PIPE ON SCHEMA $PLAYGROUND_DB.MYSCHEMA TO ROLE $PLAYGROUND_CONNECTOR_ROLE; +GRANT ALL ON ALL SCHEMAS IN DATABASE $PLAYGROUND_DB TO ROLE $PLAYGROUND_CONNECTOR_ROLE; +GRANT ALL ON FUTURE SCHEMAS IN DATABASE $PLAYGROUND_DB TO ROLE $PLAYGROUND_CONNECTOR_ROLE; GRANT ROLE $PLAYGROUND_CONNECTOR_ROLE TO ROLE ACCOUNTADMIN; EOF @@ -140,7 +143,7 @@ log "Create table foo" docker run --quiet --rm -i -e SNOWSQL_PWD="$SNOWFLAKE_PASSWORD" -e RSA_PUBLIC_KEY="$RSA_PUBLIC_KEY" kurron/snowsql --username $SNOWFLAKE_USERNAME -a $SNOWFLAKE_ACCOUNT_NAME << EOF USE ROLE $PLAYGROUND_CONNECTOR_ROLE; USE DATABASE $PLAYGROUND_DB; -USE SCHEMA PUBLIC; +USE SCHEMA MYSCHEMA; USE WAREHOUSE $PLAYGROUND_WAREHOUSE; create or replace sequence seq1; create or replace table FOO (id number default seq1.nextval, f1 string, update_ts timestamp default current_timestamp()); @@ -153,19 +156,19 @@ log "Create a view MYVIEWFORFOO" docker run --quiet --rm -i -e SNOWSQL_PWD="$SNOWFLAKE_PASSWORD" -e RSA_PUBLIC_KEY="$RSA_PUBLIC_KEY" kurron/snowsql --username $SNOWFLAKE_USERNAME -a $SNOWFLAKE_ACCOUNT_NAME << EOF USE ROLE $PLAYGROUND_CONNECTOR_ROLE; USE DATABASE $PLAYGROUND_DB; -USE SCHEMA PUBLIC; +USE SCHEMA MYSCHEMA; USE WAREHOUSE $PLAYGROUND_WAREHOUSE; create or replace view MYVIEWFORFOO as select id,f1, convert_timezone('UTC', update_ts) as update_ts from FOO; EOF docker run --quiet --rm -i -e SNOWSQL_PWD="$SNOWFLAKE_PASSWORD" -e RSA_PUBLIC_KEY="$RSA_PUBLIC_KEY" kurron/snowsql --username $SNOWFLAKE_USERNAME -a $SNOWFLAKE_ACCOUNT_NAME << EOF USE ROLE SECURITYADMIN; -grant select on view $PLAYGROUND_DB.PUBLIC.MYVIEWFORFOO to role $PLAYGROUND_CONNECTOR_ROLE; +grant select on view $PLAYGROUND_DB.MYSCHEMA.MYVIEWFORFOO to role $PLAYGROUND_CONNECTOR_ROLE; EOF # https://docs.snowflake.com/en/user-guide/jdbc-configure.html#jdbc-driver-connection-string -CONNECTION_URL="jdbc:snowflake://$SNOWFLAKE_ACCOUNT_NAME.snowflakecomputing.com/?warehouse=$PLAYGROUND_WAREHOUSE&db=$PLAYGROUND_DB&role=$PLAYGROUND_CONNECTOR_ROLE&schema=PUBLIC&user=$PLAYGROUND_USER&private_key_file=/tmp/snowflake_key.p8&private_key_file_pwd=confluent&tracing=ALL" -VIEW="$PLAYGROUND_DB.PUBLIC.MYVIEWFORFOO" +CONNECTION_URL="jdbc:snowflake://$SNOWFLAKE_ACCOUNT_NAME.snowflakecomputing.com/?warehouse=$PLAYGROUND_WAREHOUSE&db=$PLAYGROUND_DB&role=$PLAYGROUND_CONNECTOR_ROLE&schema=MYSCHEMA&user=$PLAYGROUND_USER&private_key_file=/tmp/snowflake_key.p8&private_key_file_pwd=confluent&tracing=ALL" +VIEW="$PLAYGROUND_DB.MYSCHEMA.MYVIEWFORFOO" log "Creating JDBC Snowflake Source connector" playground connector create-or-update --connector jdbc-snowflake-source << EOF From 5b6b524487219ef101961e0118f0a22e531b6c49 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 4 Nov 2024 10:07:02 +0100 Subject: [PATCH 038/659] Any client driver version lower than what is listed below will be out of support as of February 1, 2024 --- connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh b/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh index d7a0163f4c..457de05176 100755 --- a/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh +++ b/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh @@ -28,6 +28,9 @@ then # WARN JDBC type 2014 (TIMESTAMPIZ) not currently supported log "Downloading snowflake-jdbc-3.13.16.jar" wget -q https://repo1.maven.org/maven2/net/snowflake/snowflake-jdbc/3.13.16/snowflake-jdbc-3.13.16.jar + + # Any client driver version lower than what is listed below will be out of support as of February 1, 2024 based on the Snowflake Support policy https://go.snowflake.net/MjUyLVJGTy0yMjcAAAGWh1BWRfzuIKlEygL2SdqHsjvjZNQtWweD5pNexBO1BjoOYgzGFPj8zryM-ZcQLWuqmjI6kY4= + # Snowflake JDBC Driver 3.13.27 fi cd - From 24ecae4cbac27ea23d10b908b250e951c51d72c8 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 5 Nov 2024 10:12:59 +0100 Subject: [PATCH 039/659] wip --- scripts/cli/confluent-hub-plugin-list.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index 6b9fb060ae..ca3196f910 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -196,6 +196,7 @@ snowflakeinc/snowflake-kafka-connector splunk/kafka-connect-splunk spoudinc/spoud-agoora sqdata/sqdata-connector +startree/startree-native-integration streamsendio/file-chunk-sink streamsendio/file-chunk-source streamsets/streamsets-sdc From 648a2d20ad0cd853698c1cd79142e5bd50982cb0 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 5 Nov 2024 12:00:24 +0100 Subject: [PATCH 040/659] change to httpserver --- .../docker-compose.plaintext.no-auth.yml | 7 +++---- connect/connect-http-source/http-source-no-auth.sh | 9 +++++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/connect/connect-http-source/docker-compose.plaintext.no-auth.yml b/connect/connect-http-source/docker-compose.plaintext.no-auth.yml index a588fec3e0..8fdbe39cfa 100644 --- a/connect/connect-http-source/docker-compose.plaintext.no-auth.yml +++ b/connect/connect-http-source/docker-compose.plaintext.no-auth.yml @@ -6,10 +6,9 @@ services: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-http-source httpserver: - image: vdesabou/http-sink-demo + build: + context: ../../connect/connect-http-sink/httpserver hostname: httpserver container_name: httpserver ports: - - "18080:8080" - environment: - SPRING_PROFILES_ACTIVE: 'simple-auth' \ No newline at end of file + - "9006:9006" \ No newline at end of file diff --git a/connect/connect-http-source/http-source-no-auth.sh b/connect/connect-http-source/http-source-no-auth.sh index 7bca74e4e9..f5255ea2e5 100755 --- a/connect/connect-http-source/http-source-no-auth.sh +++ b/connect/connect-http-source/http-source-no-auth.sh @@ -8,16 +8,21 @@ source ${DIR}/../../scripts/utils.sh PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.no-auth.yml" +log "Set webserver to reply with 200" +curl -X PUT -H "Content-Type: application/json" --data '{"errorCode": 200}' http://localhost:9006/set-response-error-code +curl -X PUT -H "Content-Type: application/json" --data '{"store":{"book":[{"category":"reference","sold":false,"author":"Nigel Rees","title":"Sayings of the Century","price":8.95}],"bicycle":{"color":"red","price":19.95}}}' http://localhost:9006/set-response-body + log "Creating http-source connector" playground connector create-or-update --connector http-source << EOF { "tasks.max": "1", "connector.class": "io.confluent.connect.http.HttpSourceConnector", "key.converter": "org.apache.kafka.connect.storage.StringConverter", - "value.converter": "org.apache.kafka.connect.storage.StringConverter", + "value.converter": "io.confluent.connect.avro.AvroConverter", + "value.converter.schema.registry.url": "http://schema-registry:8081", "confluent.topic.bootstrap.servers": "broker:9092", "confluent.topic.replication.factor": "1", - "url": "http://httpserver:8080/api/messages", + "url": "http://httpserver:9006/", "topic.name.pattern":"http-topic-\${entityName}", "entity.names": "messages", "http.offset.mode": "SIMPLE_INCREMENTING", From 80953ca1e8893ba6361458fb1e6fbadfdd4aa25e Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 6 Nov 2024 10:38:15 +0100 Subject: [PATCH 041/659] wip --- connect/connect-salesforce-cdc-source/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/connect/connect-salesforce-cdc-source/README.md b/connect/connect-salesforce-cdc-source/README.md index a3ce794821..5345ca66b3 100644 --- a/connect/connect-salesforce-cdc-source/README.md +++ b/connect/connect-salesforce-cdc-source/README.md @@ -38,7 +38,13 @@ Example: ![Create a connected app](Screenshot3.png) * Save the new app and press Continue at the prompt. -* Look for the Consumer Key and Consumer Secret in the displayed form. Save these so you can put them in the configuration for the Salesforce connect or +* Look for the Consumer Key and Consumer Secret in the displayed form. Save these so you can put them in the configuration properties file for the Salesforce connect worker. + +**IMPORTANT !!**: for new orgs, "Username-Password Flow" is disabled by default, see the [help page](https://help.salesforce.com/s/articleView?id=release-notes.rn_security_username-password_flow_blocked_by_default.htm&release=244&type=5). + +You need to activate this (otherwise you get `{"error":"invalid_grant","error_description":"authentication failure"}`): + +![Username-Password Flow enabled](../../ccloud/fm-salesforce-cdc-source/ScreenshotOauthDisabled.jpg) ### Find your Security token From 273bebae3680b1629f9aa4e1587258b4edff8d1f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 12 Nov 2024 11:59:19 +0100 Subject: [PATCH 042/659] minor --- scripts/cli/src/bashly.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index c2084c9832..2443fb6f43 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -2100,6 +2100,9 @@ commands: default: "100" help: |- Max number of messages to display (default is 100) + + You can use -1 to display all messages + - long: --min-expected-messages arg: min-expected-messages validate: integer From 6437ac6e11cd6585c919d9109ddae1040646b053 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 12 Nov 2024 16:06:38 +0100 Subject: [PATCH 043/659] update --- secrets.tar.gpg | Bin 7452 -> 7454 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/secrets.tar.gpg b/secrets.tar.gpg index df1f7152ae2202fb1acb955afd3d64d6ff39b8f5..a6e5e02b59209b0dc51a0c0db5cccd53cee1ad3f 100644 GIT binary patch literal 7454 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 literal 7452 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 aBr}vW_~xK%lP3e;f>L_AQy&4HI<@4uT6Wd| From 427f56c43004d51d2e1f8d71d68a81705556eaed Mon Sep 17 00:00:00 2001 From: Catalin Pop Date: Wed, 13 Nov 2024 13:29:18 -0500 Subject: [PATCH 044/659] initial flink commit --- environment/mdc-plaintext/start.sh | 16 +++++++- environment/plaintext/docker-compose.yml | 42 +++++++++++++++++++++ environment/plaintext/start.sh | 4 +- scripts/cli/playground | 48 +++++++++++++++++++++++- scripts/cli/src/lib/utils_function.sh | 16 +++++++- 5 files changed, 119 insertions(+), 7 deletions(-) diff --git a/environment/mdc-plaintext/start.sh b/environment/mdc-plaintext/start.sh index c9ea06c6a6..4a2d556320 100755 --- a/environment/mdc-plaintext/start.sh +++ b/environment/mdc-plaintext/start.sh @@ -21,6 +21,18 @@ else profile_control_center_command="--profile control-center" fi +# Check if ENABLE_FLINK is set to true +profile_flink="" +if [ -z "$ENABLE_FLINK" ] +then + log "Starting services without Flink..." + playground state del flags.ENABLE_FLINK +else + log "🐿️ Starting services with Flink..." + profile_flink="--profile flink" + playground state set flags.ENABLE_FLINK 1 +fi + ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE="" DOCKER_COMPOSE_FILE_OVERRIDE=$1 if [ -f "${DOCKER_COMPOSE_FILE_OVERRIDE}" ] @@ -40,9 +52,9 @@ fi docker compose -f ../../environment/mdc-plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} build docker compose -f ../../environment/mdc-plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} down -v --remove-orphans -docker compose -f ../../environment/mdc-plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} ${profile_control_center_command} up -d --quiet-pull +docker compose -f ../../environment/mdc-plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} ${profile_control_center_command} ${profile_flink} up -d --quiet-pull log "📝 To see the actual properties file, use cli command playground container get-properties -c " -command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/mdc-plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} ${profile_control_center_command} up -d --quiet-pull" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/mdc-plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} ${profile_control_center_command} ${profile_flink} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "mdc-plaintext" log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" diff --git a/environment/plaintext/docker-compose.yml b/environment/plaintext/docker-compose.yml index 6d9294e60d..f059d758a8 100644 --- a/environment/plaintext/docker-compose.yml +++ b/environment/plaintext/docker-compose.yml @@ -606,3 +606,45 @@ services: command: - "server" - "-no-self-profiling" + + # Flink JobManager + jobmanager: + image: flink:1.20.0-scala_2.12 + profiles: + - flink + ports: + - "8081:8081" + command: jobmanager + environment: + - | + FLINK_PROPERTIES= + jobmanager.rpc.address: jobmanager + + # Flink TaskManager + taskmanager: + image: flink:1.20.0-scala_2.12 + profiles: + - flink + depends_on: + - jobmanager + command: taskmanager + scale: 1 + environment: + - | + FLINK_PROPERTIES= + jobmanager.rpc.address: jobmanager + taskmanager.numberOfTaskSlots: 2 + + # Flink SQL Client + sql-client: + image: flink:1.20.0-scala_2.12 + profiles: + - flink + command: bin/sql-client.sh + depends_on: + - jobmanager + environment: + - | + FLINK_PROPERTIES= + jobmanager.rpc.address: jobmanager + rest.address: jobmanager diff --git a/environment/plaintext/start.sh b/environment/plaintext/start.sh index 532c823e25..02a84f433b 100755 --- a/environment/plaintext/start.sh +++ b/environment/plaintext/start.sh @@ -25,9 +25,9 @@ set_profiles docker compose -f ../../environment/plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} build docker compose -f ../../environment/plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} down -v --remove-orphans -docker compose -f ../../environment/plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_rest_proxy_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_sql_datagen_command} ${profile_connect_nodes_command} ${profile_kafka_nodes_command} ${profile_schema_registry_command} up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_flink} ${profile_ksqldb_command} ${profile_rest_proxy_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_sql_datagen_command} ${profile_connect_nodes_command} ${profile_kafka_nodes_command} ${profile_schema_registry_command} up -d --quiet-pull log "📝 To see the actual properties file, use cli command playground container get-properties -c " -command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_rest_proxy_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_sql_datagen_command} ${profile_connect_nodes_command} ${profile_kafka_nodes_command} ${profile_schema_registry_command} up -d --quiet-pull" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_flink} ${profile_ksqldb_command} ${profile_rest_proxy_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_sql_datagen_command} ${profile_connect_nodes_command} ${profile_kafka_nodes_command} ${profile_schema_registry_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "plaintext" log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" diff --git a/scripts/cli/playground b/scripts/cli/playground index f55c2e71ce..626f54fcb6 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8529,6 +8529,18 @@ function set_profiles() { playground state set flags.ENABLE_CONTROL_CENTER 1 fi + # Check if ENABLE_FLINK is set to true + profile_flink="" + if [ -z "$ENABLE_FLINK" ] + then + log "Starting services without Flink..." + playground state del flags.ENABLE_FLINK + else + log "🐿️ Starting services with Flink..." + profile_flink="--profile flink" + playground state set flags.ENABLE_FLINK 1 + fi + profile_ksqldb_command="" if [ -z "$ENABLE_KSQLDB" ] then @@ -11979,7 +11991,7 @@ fi } function load_env_variables () { - for item in {ENABLE_CONTROL_CENTER,ENABLE_KSQLDB,ENABLE_RESTPROXY,ENABLE_JMX_GRAFANA,ENABLE_KCAT,ENABLE_CONDUKTOR,SQL_DATAGEN,ENABLE_KAFKA_NODES,ENABLE_CONNECT_NODES} + for item in {ENABLE_CONTROL_CENTER,ENABLE_FLINK,ENABLE_KSQLDB,ENABLE_RESTPROXY,ENABLE_JMX_GRAFANA,ENABLE_KCAT,ENABLE_CONDUKTOR,SQL_DATAGEN,ENABLE_KAFKA_NODES,ENABLE_CONNECT_NODES} do i=$(playground state get "flags.${item}") if [ "$i" != "" ] @@ -13672,6 +13684,12 @@ playground_run_command() { export ENABLE_CONTROL_CENTER=true fi + if [[ -n "$enable_flink" ]] + then + array_flag_list+=("--enable-flink") + export ENABLE_FLINK=true + fi + if [[ -n "$enable_conduktor" ]] then array_flag_list+=("--enable-conduktor") @@ -14272,6 +14290,13 @@ playground_run_command() { else unset 'options[28]' fi + if [ ! -z $ENABLE_FLINK ] + then + unset 'options[20]' + else + unset 'options[29]' + fi + missing_env="" declare -a missing_env_list=() @@ -14480,6 +14505,19 @@ playground_run_command() { interactive_enable_c3="" fi + if [[ $res == *"$MENU_ENABLE_FL"* ]] + then + array_flag_list+=("--enable-flink") + export ENABLE_FLINK=true + interactive_enable_flink="true" + fi + if [[ $res == *"$MENU_DISABLE_FL"* ]] + then + array_flag_list=("${array_flag_list[@]/"--enable-flink"}") + unset ENABLE_FLINK + interactive_enable_flink="" + fi + if [[ $res == *"$MENU_ENABLE_RP"* ]] then array_flag_list+=("--enable-rest-proxy") @@ -14780,6 +14818,14 @@ playground_run_command() { fi fi + if [ "$interactive_enable_flink" == "true" ] + then + if [[ -n "$force_interactive_repro" ]] + then + force_enable --enable-flink ENABLE_FLINK + fi + fi + if [ "$interactive_enable_conduktor" == "true" ] then if [[ -n "$force_interactive_repro" ]] diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 13618e3e32..66f37cd7c8 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -493,6 +493,18 @@ function set_profiles() { playground state set flags.ENABLE_CONTROL_CENTER 1 fi + # Check if ENABLE_FLINK is set to true + profile_flink="" + if [ -z "$ENABLE_FLINK" ] + then + log "Starting services without Flink..." + playground state del flags.ENABLE_FLINK + else + log "🐿️ Starting services with Flink..." + profile_flink="--profile flink" + playground state set flags.ENABLE_FLINK 1 + fi + profile_ksqldb_command="" if [ -z "$ENABLE_KSQLDB" ] then @@ -531,7 +543,7 @@ function set_profiles() { profile_kcat_command="" if [ -z "$ENABLE_KCAT" ] then - log "🛑 kcat is disabled" + log "🛑 kcat is disabled3" playground state del flags.ENABLE_KCAT else log "🧰 kcat is enabled" @@ -4012,7 +4024,7 @@ fi } function load_env_variables () { - for item in {ENABLE_CONTROL_CENTER,ENABLE_KSQLDB,ENABLE_RESTPROXY,ENABLE_JMX_GRAFANA,ENABLE_KCAT,ENABLE_CONDUKTOR,SQL_DATAGEN,ENABLE_KAFKA_NODES,ENABLE_CONNECT_NODES} + for item in {ENABLE_CONTROL_CENTER,ENABLE_FLINK,ENABLE_KSQLDB,ENABLE_RESTPROXY,ENABLE_JMX_GRAFANA,ENABLE_KCAT,ENABLE_CONDUKTOR,SQL_DATAGEN,ENABLE_KAFKA_NODES,ENABLE_CONNECT_NODES} do i=$(playground state get "flags.${item}") if [ "$i" != "" ] From 6ab0d604c5f9292ca762a01c09e24124f973ede1 Mon Sep 17 00:00:00 2001 From: Catalin Pop Date: Thu, 14 Nov 2024 16:18:06 -0500 Subject: [PATCH 045/659] initial flink commit --- environment/plaintext/docker-compose.yml | 35 +++++-- flink/README.md | 4 + flink/conf/console_info_log4j.properties | 9 ++ flink/conf/console_trace_log4j.properties | 9 ++ flink/flink_app_mode/README.md | 19 ++++ flink/flink_app_mode/docker-compose.yml | 12 +++ flink/flink_app_mode/start.sh | 7 ++ flink/flink_app_mode/stop.sh | 6 ++ flink/flink_session_mode/README.md | 15 +++ flink/flink_session_mode/docker-compose.yml | 15 +++ flink/flink_session_mode/start.sh | 3 + flink/flink_session_mode/stop.sh | 7 ++ flink/flink_session_sql_mode/README.md | 24 +++++ .../flink_session_sql_mode/docker-compose.yml | 47 +++++++++ flink/flink_session_sql_mode/start.sh | 7 ++ flink/flink_session_sql_mode/stop.sh | 6 ++ scripts/cli/confluent-hub-plugin-list.txt | 1 + scripts/cli/confluent-kafka-region-list.txt | 99 ------------------- scripts/cli/playground | 4 +- scripts/cli/src/lib/utils_function.sh | 6 +- scripts/utils.sh | 6 ++ 21 files changed, 227 insertions(+), 114 deletions(-) create mode 100644 flink/README.md create mode 100644 flink/conf/console_info_log4j.properties create mode 100644 flink/conf/console_trace_log4j.properties create mode 100644 flink/flink_app_mode/README.md create mode 100644 flink/flink_app_mode/docker-compose.yml create mode 100755 flink/flink_app_mode/start.sh create mode 100755 flink/flink_app_mode/stop.sh create mode 100644 flink/flink_session_mode/README.md create mode 100644 flink/flink_session_mode/docker-compose.yml create mode 100755 flink/flink_session_mode/start.sh create mode 100755 flink/flink_session_mode/stop.sh create mode 100644 flink/flink_session_sql_mode/README.md create mode 100644 flink/flink_session_sql_mode/docker-compose.yml create mode 100755 flink/flink_session_sql_mode/start.sh create mode 100755 flink/flink_session_sql_mode/stop.sh diff --git a/environment/plaintext/docker-compose.yml b/environment/plaintext/docker-compose.yml index f059d758a8..fc0bceaa60 100644 --- a/environment/plaintext/docker-compose.yml +++ b/environment/plaintext/docker-compose.yml @@ -609,42 +609,57 @@ services: # Flink JobManager jobmanager: - image: flink:1.20.0-scala_2.12 + image: flink:${FLINK_TAG} + hostname: jobmanager + container_name: jobmanager profiles: - flink ports: - - "8081:8081" + - "18081:18081" # Expose port 18081 for REST API and Web UI command: jobmanager environment: - | FLINK_PROPERTIES= - jobmanager.rpc.address: jobmanager + jobmanager.rpc.address: jobmanager + rest.port: 18081 + taskmanager.numberOfTaskSlots: 4 # Flink TaskManager taskmanager: - image: flink:1.20.0-scala_2.12 + image: flink:${FLINK_TAG} + hostname: taskmanager + container_name: taskmanager profiles: - flink depends_on: - jobmanager command: taskmanager - scale: 1 environment: - | FLINK_PROPERTIES= jobmanager.rpc.address: jobmanager - taskmanager.numberOfTaskSlots: 2 + rest.address: jobmanager + rest.port: 18081 + taskmanager.numberOfTaskSlots: 4 - # Flink SQL Client + # Flink SQL Client sql-client: - image: flink:1.20.0-scala_2.12 + image: flink:${FLINK_TAG} + hostname: sql-client + container_name: sql-client profiles: - flink - command: bin/sql-client.sh + depends_on: - jobmanager + stdin_open: true + tty: true + command: bin/sql-client.sh environment: - | FLINK_PROPERTIES= jobmanager.rpc.address: jobmanager - rest.address: jobmanager + rest.address: jobmanager + rest.port: 18081 + deployment.gateway-address: jobmanager + deployment.gateway-port: 18081 \ No newline at end of file diff --git a/flink/README.md b/flink/README.md new file mode 100644 index 0000000000..80880eb06e --- /dev/null +++ b/flink/README.md @@ -0,0 +1,4 @@ +# TO DO + +- [ ] need to update this README.md so this way it points the difference between the 3 projects and how to deploy +- [ ] Need to add env variable feature such that when enabled, it will allow users to use configuration files rather than env variables \ No newline at end of file diff --git a/flink/conf/console_info_log4j.properties b/flink/conf/console_info_log4j.properties new file mode 100644 index 0000000000..cda65f3c61 --- /dev/null +++ b/flink/conf/console_info_log4j.properties @@ -0,0 +1,9 @@ +# Set root logger level to INFO and define appender +rootLogger.level = INFO +rootLogger.appenderRef.console.ref = ConsoleAppender + +# Console appender configuration +appender.console.name = ConsoleAppender +appender.console.type = Console +appender.console.layout.type = PatternLayout +appender.console.layout.pattern = [%d{ISO8601}] %-5p %c{1} - %m%n \ No newline at end of file diff --git a/flink/conf/console_trace_log4j.properties b/flink/conf/console_trace_log4j.properties new file mode 100644 index 0000000000..791bc0e079 --- /dev/null +++ b/flink/conf/console_trace_log4j.properties @@ -0,0 +1,9 @@ +# Set root logger level to DEBUG and define appender +rootLogger.level = TRACE +rootLogger.appenderRef.console.ref = ConsoleAppender + +# Console appender configuration +appender.console.name = ConsoleAppender +appender.console.type = Console +appender.console.layout.type = PatternLayout +appender.console.layout.pattern = [%d{ISO8601}] %-5p %c{1} - %m%n \ No newline at end of file diff --git a/flink/flink_app_mode/README.md b/flink/flink_app_mode/README.md new file mode 100644 index 0000000000..490a5ccaf1 --- /dev/null +++ b/flink/flink_app_mode/README.md @@ -0,0 +1,19 @@ +# Apache Flink in Application Mode with Docker Compose + +This setup runs Apache Flink in **Application Mode** using Docker Compose. If you wish to deploy a application, ensure to specify environment variable: + +``` +export FLINK_JAR_PATH=/path/to/my/file.jar +``` + +## How to Start + +```bash +./start.sh +``` + +## How to Stop + +```bash +./stop.sh +``` \ No newline at end of file diff --git a/flink/flink_app_mode/docker-compose.yml b/flink/flink_app_mode/docker-compose.yml new file mode 100644 index 0000000000..f2f1229235 --- /dev/null +++ b/flink/flink_app_mode/docker-compose.yml @@ -0,0 +1,12 @@ +version: '3.8' + +services: + jobmanager: + image: flink:latest + command: jobmanager + ports: + - "8081:8081" + volumes: + - ${FLINK_JAR_PATH}:/opt/flink/job.jar + environment: + - FLINK_PROPERTIES= diff --git a/flink/flink_app_mode/start.sh b/flink/flink_app_mode/start.sh new file mode 100755 index 0000000000..0ac6089959 --- /dev/null +++ b/flink/flink_app_mode/start.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +# loading env variables +source ${DIR}/../../scripts/utils.sh + +docker-compose up -d \ No newline at end of file diff --git a/flink/flink_app_mode/stop.sh b/flink/flink_app_mode/stop.sh new file mode 100755 index 0000000000..d2aaf929a4 --- /dev/null +++ b/flink/flink_app_mode/stop.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +stop_all "$DIR" diff --git a/flink/flink_session_mode/README.md b/flink/flink_session_mode/README.md new file mode 100644 index 0000000000..a114539cdc --- /dev/null +++ b/flink/flink_session_mode/README.md @@ -0,0 +1,15 @@ +# Apache Flink in Session Mode with Docker Compose + +This setup runs Apache Flink in **Session Mode** using Docker Compose. + +## How to Start + +```bash +./start.sh +``` + +## How to Stop + +```bash +./stop.sh +``` \ No newline at end of file diff --git a/flink/flink_session_mode/docker-compose.yml b/flink/flink_session_mode/docker-compose.yml new file mode 100644 index 0000000000..c168b135a8 --- /dev/null +++ b/flink/flink_session_mode/docker-compose.yml @@ -0,0 +1,15 @@ +version: '3.8' + +services: + jobmanager: + image: flink:${FLINK_TAG} + command: jobmanager + ports: + - "8081:8081" + + taskmanager: + image: flink:${FLINK_TAG} + command: taskmanager + scale: 2 + depends_on: + - jobmanager \ No newline at end of file diff --git a/flink/flink_session_mode/start.sh b/flink/flink_session_mode/start.sh new file mode 100755 index 0000000000..80b5727c14 --- /dev/null +++ b/flink/flink_session_mode/start.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker-compose up -d \ No newline at end of file diff --git a/flink/flink_session_mode/stop.sh b/flink/flink_session_mode/stop.sh new file mode 100755 index 0000000000..9e39920efa --- /dev/null +++ b/flink/flink_session_mode/stop.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +echo "Pops ${DIR}" +source ${DIR}/../../scripts/utils.sh + +stop_all "$DIR" \ No newline at end of file diff --git a/flink/flink_session_sql_mode/README.md b/flink/flink_session_sql_mode/README.md new file mode 100644 index 0000000000..a3b6941a9a --- /dev/null +++ b/flink/flink_session_sql_mode/README.md @@ -0,0 +1,24 @@ +# Apache Flink in Session Mode with SQL Client using Docker Compose + +This setup runs Apache Flink in **Session Mode** with the **SQL Client**. + +## How to attach to SQL client +``` +docker attach sql-client +``` +When quitting out of the SQL client, the container will stop working. If you wish to restart the SQL Client, simply run: +``` +docker-compose start sql-client +``` + +## How to Start + +```bash +./start.sh +``` + +## How to Stop + +```bash +./stop.sh +``` \ No newline at end of file diff --git a/flink/flink_session_sql_mode/docker-compose.yml b/flink/flink_session_sql_mode/docker-compose.yml new file mode 100644 index 0000000000..f8978c5ae4 --- /dev/null +++ b/flink/flink_session_sql_mode/docker-compose.yml @@ -0,0 +1,47 @@ +version: '3.8' + +services: + # Flink JobManager + jobmanager: + image: flink:${FLINK_TAG} + hostname: jobmanager + container_name: jobmanager + ports: + - "8081:8081" + command: jobmanager + environment: + - | + FLINK_PROPERTIES= + jobmanager.rpc.address: jobmanager + + # Flink TaskManager + taskmanager: + image: flink:${FLINK_TAG} + hostname: taskmanager + container_name: taskmanager + depends_on: + - jobmanager + command: taskmanager + environment: + - | + FLINK_PROPERTIES= + jobmanager.rpc.address: jobmanager + rest.address: jobmanager + taskmanager.numberOfTaskSlots: 4 + + # Flink SQL Client + sql-client: + image: flink:${FLINK_TAG} + hostname: sql-client + container_name: sql-client + depends_on: + - jobmanager + stdin_open: true + tty: true + command: bin/sql-client.sh + environment: + - | + FLINK_PROPERTIES= + jobmanager.rpc.address: jobmanager + rest.address: jobmanager + deployment.gateway-address: jobmanager \ No newline at end of file diff --git a/flink/flink_session_sql_mode/start.sh b/flink/flink_session_sql_mode/start.sh new file mode 100755 index 0000000000..0ac6089959 --- /dev/null +++ b/flink/flink_session_sql_mode/start.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +# loading env variables +source ${DIR}/../../scripts/utils.sh + +docker-compose up -d \ No newline at end of file diff --git a/flink/flink_session_sql_mode/stop.sh b/flink/flink_session_sql_mode/stop.sh new file mode 100755 index 0000000000..e127f27883 --- /dev/null +++ b/flink/flink_session_sql_mode/stop.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +stop_all "$DIR" \ No newline at end of file diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index 6b9fb060ae..ca3196f910 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -196,6 +196,7 @@ snowflakeinc/snowflake-kafka-connector splunk/kafka-connect-splunk spoudinc/spoud-agoora sqdata/sqdata-connector +startree/startree-native-integration streamsendio/file-chunk-sink streamsendio/file-chunk-source streamsets/streamsets-sdc diff --git a/scripts/cli/confluent-kafka-region-list.txt b/scripts/cli/confluent-kafka-region-list.txt index 518e686afa..e69de29bb2 100644 --- a/scripts/cli/confluent-kafka-region-list.txt +++ b/scripts/cli/confluent-kafka-region-list.txt @@ -1,99 +0,0 @@ -Name/Region -Bahrain(me-south-1)/me-south-1 -Belgium(europe-west1)/europe-west1 -Calgary(ca-west-1)/ca-west-1 -Canada(ca-central-1)/ca-central-1 -CapeTown(af-south-1)/af-south-1 -Dallas(us-south1)/us-south1 -Dammam(me-central2)/me-central2 -Delhi(asia-south2)/asia-south2 -Doha(me-central1)/me-central1 -Doha(qatarcentral)/qatarcentral -Dubai(uaenorth)/uaenorth -Finland(europe-north1)/europe-north1 -Frankfurt(eu-central-1)/eu-central-1 -Frankfurt(europe-west3)/europe-west3 -Frankfurt(germanywestcentral)/germanywestcentral -Gävle(swedencentral)/swedencentral -HongKong(ap-east-1)/ap-east-1 -HongKong(asia-east2)/asia-east2 -HongKong(eastasia)/eastasia -Hyderabad(ap-south-2)/ap-south-2 -Iowa(centralus)/centralus -Iowa(us-central1)/us-central1 -Ireland(eu-west-1)/eu-west-1 -Ireland(northeurope)/northeurope -Jakarta(ap-southeast-3)/ap-southeast-3 -Jakarta(asia-southeast2)/asia-southeast2 -Johannesburg/southafricanorth -(southafricanorth)/ -LasVegas(us-west4)/us-west4 -London(eu-west-2)/eu-west-2 -London(europe-west2)/europe-west2 -London(uksouth)/uksouth -LosAngeles(us-west2)/us-west2 -Madrid(europe-southwest1)/europe-southwest1 -Melbourne(ap-southeast-4)/ap-southeast-4 -Melbourne/australia-southeast2 -(australia-southeast2)/ -MexicoCentral(mexicocentral)/mexicocentral -Milan(eu-south-1)/eu-south-1 -Milan(europe-west8)/europe-west8 -Milan(italynorth)/italynorth -Montreal/northamerica-northeast1 -(northamerica-northeast1)/ -Mumbai(ap-south-1)/ap-south-1 -Mumbai(asia-south1)/asia-south1 -N.Virginia(us-east-1)/us-east-1 -N.Virginia(us-east4)/us-east4 -Netherlands(europe-west4)/europe-west4 -Netherlands(westeurope)/westeurope -NewSouthWales/australiaeast -(australiaeast)/ -Ohio(us-east-2)/us-east-2 -Oregon(us-west-2)/us-west-2 -Oregon(us-west1)/us-west1 -Osaka(ap-northeast-3)/ap-northeast-3 -Osaka(asia-northeast2)/asia-northeast2 -Oslo(norwayeast)/norwayeast -Paris(eu-west-3)/eu-west-3 -Paris(europe-west9)/europe-west9 -Paris(francecentral)/francecentral -Phoenix(westus3)/westus3 -Pune(centralindia)/centralindia -S.Carolina(us-east1)/us-east1 -SaltLakeCity(us-west3)/us-west3 -Santiago(southamerica-west1)/southamerica-west1 -SaoPaulo(southamerica-east1)/southamerica-east1 -SaoPaulostate(brazilsouth)/brazilsouth -Seoul(ap-northeast-2)/ap-northeast-2 -Seoul(asia-northeast3)/asia-northeast3 -Seoul(koreacentral)/koreacentral -Singapore(ap-southeast-1)/ap-southeast-1 -Singapore(asia-southeast1)/asia-southeast1 -Singapore(southeastasia)/southeastasia -Spain(eu-south-2)/eu-south-2 -Spain(spaincentral)/spaincentral -Stockholm(eu-north-1)/eu-north-1 -Sydney(ap-southeast-2)/ap-southeast-2 -Sydney(australia-southeast1)/australia-southeast1 -SãoPaulo(sa-east-1)/sa-east-1 -Taiwan(asia-east1)/asia-east1 -TelAviv(il-central-1)/il-central-1 -TelAviv(me-west1)/me-west1 -Texas(southcentralus)/southcentralus -Tokyo(ap-northeast-1)/ap-northeast-1 -Tokyo(asia-northeast1)/asia-northeast1 -Tokyo(japaneast)/japaneast -Toronto(canadacentral)/canadacentral -Toronto/northamerica-northeast2 -(northamerica-northeast2)/ -Turin(europe-west12)/europe-west12 -UAE(me-central-1)/me-central-1 -Virginia(eastus)/eastus -Virginia(eastus2)/eastus2 -Warsaw(europe-central2)/europe-central2 -Washington(westus2)/westus2 -Zurich(eu-central-2)/eu-central-2 -Zurich(europe-west6)/europe-west6 -Zurich(switzerlandnorth)/switzerlandnorth diff --git a/scripts/cli/playground b/scripts/cli/playground index 626f54fcb6..41f3c544ec 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8533,10 +8533,10 @@ function set_profiles() { profile_flink="" if [ -z "$ENABLE_FLINK" ] then - log "Starting services without Flink..." + log "🛑 Starting services without Flink" playground state del flags.ENABLE_FLINK else - log "🐿️ Starting services with Flink..." + log "🐿️ Starting services with Flink" profile_flink="--profile flink" playground state set flags.ENABLE_FLINK 1 fi diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 66f37cd7c8..3ab80ab655 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -497,10 +497,10 @@ function set_profiles() { profile_flink="" if [ -z "$ENABLE_FLINK" ] then - log "Starting services without Flink..." + log "🛑 Starting services without Flink" playground state del flags.ENABLE_FLINK else - log "🐿️ Starting services with Flink..." + log "🐿️ Starting services with Flink" profile_flink="--profile flink" playground state set flags.ENABLE_FLINK 1 fi @@ -543,7 +543,7 @@ function set_profiles() { profile_kcat_command="" if [ -z "$ENABLE_KCAT" ] then - log "🛑 kcat is disabled3" + log "🛑 kcat is disabled" playground state del flags.ENABLE_KCAT else log "🧰 kcat is enabled" diff --git a/scripts/utils.sh b/scripts/utils.sh index 6ccad08ae0..51460a7ba0 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -22,6 +22,12 @@ then fi fi +if [ -z "$FLINK_TAG" ] +then + # FLINK_TAG is not set, use default: + export FLINK_TAG=latest +fi + # Setting up TAG environment variable # if [ -z "$TAG" ] From 3e9a91193145c63a761024ec40e2e37884a238b5 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 14 Nov 2024 22:34:48 +0100 Subject: [PATCH 046/659] playground schema set-normalize --- scripts/cli/completions.bash | 860 +++++++++--------- scripts/cli/playground | 177 +++- scripts/cli/playground.json | 27 +- scripts/cli/playground.yaml | 26 + scripts/cli/src/bashly.yml | 20 + .../cli/src/commands/schema/set-normalize.sh | 30 + 6 files changed, 712 insertions(+), 428 deletions(-) create mode 100644 scripts/cli/src/commands/schema/set-normalize.sh diff --git a/scripts/cli/completions.bash b/scripts/cli/completions.bash index 6a8a3652e1..a6874380e9 100644 --- a/scripts/cli/completions.bash +++ b/scripts/cli/completions.bash @@ -32,48 +32,44 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'config open-ccloud-connector-in-browser automatically'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'connector open-ccloud-connector-in-browser'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'config open-ccloud-connector-in-browser browser'*) + *'config open-ccloud-connector-in-browser automatically'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector offsets get-offsets-request-status'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'tcp-proxy toggle-writes-service'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + *'config open-ccloud-connector-in-browser browser'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'container set-environment-variables'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy toggle-writes-client'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + *'connector offsets get-offsets-request-status'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tcp-proxy toggle-reads-service'*'--connection-id') + *'tcp-proxy toggle-writes-service'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; + *'topic set-schema-compatibility'*'--compatibility') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") + ;; + *'connector-plugin search-jar'*'--connector-plugin') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; - *'topic set-schema-compatibility'*'--compatibility') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") + *'tcp-proxy toggle-writes-client'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'connector offsets get-offsets-request-status'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'tcp-proxy toggle-reads-service'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; *'connector open-ccloud-connector-in-browser'*'-c') @@ -88,26 +84,30 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'ec2 sync-repro-folder ec2-to-local'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'connector offsets get-offsets-request-status'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'connector-plugin versions'*'--connector-plugin') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") + *'ec2 sync-repro-folder ec2-to-local'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; *'connector show-config-parameters'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'topic produce'*'--value-subject-name-strategy') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") + *'connector-plugin versions'*'--connector-plugin') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; *'connector open-ccloud-connector-in-browser'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--browser --connector --help -c -h")" -- "$cur") ;; + *'topic produce'*'--value-subject-name-strategy') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") + ;; + *'connector create-or-update'*'--initial-state') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "RUNNING PAUSED STOPPED")" -- "$cur") ;; @@ -120,10 +120,6 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'tcp-proxy get-connections'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") - ;; - *'topic produce'*'--key-subject-name-strategy') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") ;; @@ -132,43 +128,43 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'config open-ccloud-connector-in-browser'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h automatically browser")" -- "$cur") + *'tcp-proxy get-connections'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; *'schema set-compatibility'*'--compatibility') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; - *'container set-environment-variables'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'connector create-or-update'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'config open-ccloud-connector-in-browser'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h automatically browser")" -- "$cur") ;; *'topic set-schema-compatibility'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; + *'container set-environment-variables'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + *'debug generate-diagnostics'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'config container-kill-all-before-run'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'connector create-or-update'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'ec2 sync-repro-folder local-to-ec2'*'-i') + *'ec2 sync-repro-folder ec2-to-local'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'ec2 sync-repro-folder ec2-to-local'*'-i') + *'ec2 sync-repro-folder local-to-ec2'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'tcp-proxy toggle-accept-connections'*) + *'config container-kill-all-before-run'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -180,15 +176,19 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'tcp-proxy toggle-accept-connections'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + *'ec2 sync-repro-folder ec2-to-local'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'connector show-config-parameters'*'-c') + *'connector offsets reset'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector select-config'*'--connector') + *'connector offsets alter'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -196,19 +196,19 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'connector offsets reset'*'--connector') + *'connector show-config-parameters'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector offsets alter'*'--connector') + *'connector select-config'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'schema set-compatibility'*'--subject') + *'schema get-compatibility'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'schema get-compatibility'*'--subject') + *'schema set-compatibility'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; @@ -220,23 +220,19 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'connector offsets get'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'connector show-config-parameters'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-refresh --help --only-show-json --open --verbose -c -h -o -v")" -- "$cur") ;; - *'topic produce'*'--compression-codec') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "gzip snappy lz4 zstd")" -- "$cur") + *'connector show-config'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'debug flight-recorder'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector show-config-parameters'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-refresh --help --only-show-json --open --verbose -c -h -o -v")" -- "$cur") - ;; - - *'connector show-config'*'--connector') + *'connector offsets get'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -244,166 +240,170 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'debug enable-remote-debugging'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'container change-jdk'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic produce'*'--compression-codec') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "gzip snappy lz4 zstd")" -- "$cur") ;; *'tcp-proxy toggle-writes-service'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'topic get-number-records'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'debug enable-remote-debugging'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic produce'*'--validate-config') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") + *'container change-jdk'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic display-consumer-offsets'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --verbose -h -v")" -- "$cur") + *'topic get-number-records'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'tcp-proxy delay'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'tcp-proxy break'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + *'topic produce'*'--validate-config') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") ;; - *'connector log-level'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'tcp-proxy break'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'tcp-proxy toggle-writes-client'*) + *'tcp-proxy toggle-reads-service'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'tools install-vscode-extension'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'debug block-traffic'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy toggle-reads-service'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'connector log-level'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'topic set-schema-compatibility'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --topic --verbose -h -t -v")" -- "$cur") ;; - *'connector show-lag'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'topic display-consumer-offsets'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --verbose -h -v")" -- "$cur") ;; - *'tcp-proxy toggle-reads-client'*) + *'tcp-proxy toggle-writes-client'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'debug enable-remote-debugging'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'tools install-vscode-extension'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector snippets'*'--converter') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "avro protobuf json-schema json json-schema-enabled string bytearray")" -- "$cur") + *'tcp-proxy toggle-reads-client'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'debug flight-recorder'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") + *'tools read-parquet-file'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") ;; - *'update-version'*'--connector-jar') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") + *'debug enable-remote-debugging'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + ;; + + *'connector show-lag'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'connector-plugin search-jar'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; - *'update-version'*'--connector-zip') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") + *'debug flight-recorder'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") ;; - *'tools read-parquet-file'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") + *'connector snippets'*'--converter') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "avro protobuf json-schema json json-schema-enabled string bytearray")" -- "$cur") ;; *'container change-jdk'*'--version') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "8 11 17 21 22")" -- "$cur") ;; - *'connector create-or-update'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'update-version'*'--connector-zip') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") ;; - *'container unpause'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'update-version'*'--connector-jar') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") ;; - *'topic consume'*'--value-subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'debug generate-diagnostics'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'connector restart'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug generate-diagnostics'*'-c') + *'debug thread-dump'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug thread-dump'*'--container') + *'container unpause'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container restart'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic produce'*'--compatibility') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; - *'connector unpause'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'connector create-or-update'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'connector create-or-update'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container restart'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic produce'*'--compatibility') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") + *'topic consume'*'--value-subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'connector update'*'--connector') + *'connector unpause'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector delete'*'--connector') + *'connector create-or-update'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector resume'*'--connector') + *'connector delete'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector-plugin search-jar'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--class --connector-plugin --connector-tag --help -c -h")" -- "$cur") + *'container resume'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'connector-plugin versions'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; + *'connector resume'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + *'connector status'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; + *'schema set-normalize'*'--value') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "true false")" -- "$cur") + ;; + *'debug block-traffic'*'--action') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") ;; @@ -412,35 +412,35 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container resume'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'debug heap-dump'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector-plugin search-jar'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--class --connector-plugin --connector-tag --help -c -h")" -- "$cur") ;; - *'topic consume'*'--key-subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'connector update'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug log-level set'*'--level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'container pause'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'connector pause'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug generate-diagnostics'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'debug log-level set'*'--level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; *'get-jmx-metrics'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container pause'*'--container') + *'debug heap-dump'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + + *'container get-properties'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -448,108 +448,100 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'tools read-avro-file'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") + *'connector log-level'*'--level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'topic get-number-records'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'debug generate-diagnostics'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; *'tcp-proxy close-connection'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'container get-properties'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'connector log-level'*'--level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") - ;; - *'connector create-or-update'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --initial-state --level --offsets --package --skip-automatic-connector-config --validate --verbose --wait-for-zero-lag -c -h -l -p -v")" -- "$cur") ;; - *'container kill'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic get-number-records'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'container logs'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'tools read-avro-file'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") ;; - *'debug block-traffic'*'--port') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") + *'topic consume'*'--key-subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'debug tcp-dump'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector offsets reset'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'container exec'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'ec2 create'*'--instance-type') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "c1.medium c1.xlarge c3.2xlarge c3.4xlarge c3.8xlarge c3.large c3.xlarge c4.2xlarge c4.4xlarge c4.large c4.xlarge m1.large m1.medium m1.small m1.xlarge m2.2xlarge m2.4xlarge m2.xlarge m3.2xlarge m3.large m3.medium m3.xlarge m4.10xlarge m4.2xlarge m4.4xlarge m4.large m4.xlarge t1.micro t2.large t2.medium t2.micro t2.nano t2.small t3.2xlarge")" -- "$cur") + *'connector stop'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'config check-repo-version'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'tcp-proxy get-connections'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; *'connector select-config'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector stop'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'repro bootstrap'*'--pipeline') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro --sink-only "$cur")")" -- "$cur") ;; - *'connector offsets alter'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container logs'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'repro bootstrap'*'--producer') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") ;; - *'repro bootstrap'*'--pipeline') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro --sink-only "$cur")")" -- "$cur") - ;; - - *'connector offsets reset'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'tools read-parquet-file'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") + *'ec2 create'*'--instance-type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "c1.medium c1.xlarge c3.2xlarge c3.4xlarge c3.8xlarge c3.large c3.xlarge c4.2xlarge c4.4xlarge c4.large c4.xlarge m1.large m1.medium m1.small m1.xlarge m2.2xlarge m2.4xlarge m2.xlarge m3.2xlarge m3.large m3.medium m3.xlarge m4.10xlarge m4.2xlarge m4.4xlarge m4.large m4.xlarge t1.micro t2.large t2.medium t2.micro t2.nano t2.small t3.2xlarge")" -- "$cur") ;; - *'tcp-proxy get-connections'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'debug block-traffic'*'--port') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; *'tcp-proxy start'*'--hostname') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'config check-repo-version'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + *'connector-plugin versions'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-plugin --force-refresh --help --last -c -h")" -- "$cur") ;; - *'schema get-mode'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'debug tcp-dump'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container ssh'*'--container') + *'connector offsets alter'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'container kill'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'config folder_zip_or_jar'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'tools read-parquet-file'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") ;; *'run'*'--cluster-environment') @@ -564,40 +556,44 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; + *'schema register'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + ;; + *'remove-all-docker-images'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'schema set-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --subject --verbose -h -v")" -- "$cur") + *'schema get-mode'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; *'schema get-compatibility'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; - *'schema set-mode'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'debug java-debug'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "enable disable")" -- "$cur") ;; - *'topic get-number-records'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") + *'container ssh'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug java-debug'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "enable disable")" -- "$cur") + *'schema set-mode'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'schema register'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'topic get-number-records'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") ;; - *'schema register'*'--schema') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + *'schema set-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --subject --verbose -h -v")" -- "$cur") ;; - *'cleanup-cloud-resources'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--force --help --resource -h")" -- "$cur") + *'config folder_zip_or_jar'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'connector offsets alter'*) @@ -612,20 +608,32 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") ;; + *'schema register'*'--schema') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + ;; + *'debug flight-recorder'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'cleanup-cloud-resources'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--force --help --resource -h")" -- "$cur") + ;; + *'connector offsets reset'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; + *'connector offsets get'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + *'tools read-parquet-file'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'connector offsets get'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'schema delete'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; *'container change-jdk'*'-c') @@ -640,32 +648,28 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") ;; - *'schema delete'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'container exec'*'--shell') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'debug flight-recorder'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help -c -h")" -- "$cur") + *'connector show-config'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-rest-endpoint --help --verbose -c -h -v")" -- "$cur") ;; - *'debug block-traffic'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'cleanup-cloud-details'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'topic describe'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'debug log-level set'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") - ;; - - *'container exec'*'--shell') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") + *'ec2 sync-repro-folder'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h ec2-to-local local-to-ec2")" -- "$cur") ;; - *'connector log-level'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'schema set-mode'*'--mode') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") ;; *'connector log-level'*'-c') @@ -676,32 +680,28 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'schema set-mode'*'--mode') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") - ;; - - *'connector offsets get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'repro bootstrap'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") ;; - *'connector show-config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-rest-endpoint --help --verbose -c -h -v")" -- "$cur") + *'debug log-level set'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'repro bootstrap'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") + *'connector offsets get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'cleanup-cloud-details'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'debug block-traffic'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'ec2 sync-repro-folder'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h ec2-to-local local-to-ec2")" -- "$cur") + *'connector log-level'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'tools read-avro-file'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + *'debug flight-recorder'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help -c -h")" -- "$cur") ;; *'topic produce'*'--topic') @@ -712,22 +712,26 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'topic consume'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'connector show-lag'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug tcp-dump'*'--port') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") + *'tools read-avro-file'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'connector show-lag'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'schema set-normalize'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --value --verbose -h -v")" -- "$cur") ;; *'ec2 delete'*'--instance') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") ;; + *'topic consume'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + ;; + *'container ssh'*'--shell') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; @@ -736,12 +740,8 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --version -c -h")" -- "$cur") ;; - *'container restart'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'debug thread-dump'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'debug tcp-dump'*'--port') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; *'update-version'*'--tag') @@ -756,30 +756,30 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'debug log-level set'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --level --package -h -l -p")" -- "$cur") - ;; - - *'debug block-traffic'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --destination --help --port -c -h")" -- "$cur") - ;; - - *'connector open-docs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") + *'run'*'--cluster-region') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-kafka-region-list "$cur")")" -- "$cur") ;; *'connector restart'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'run'*'--cluster-region') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-kafka-region-list "$cur")")" -- "$cur") + *'connector unpause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'topic delete'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; + *'connector open-docs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") + ;; + + *'debug log-level set'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --level --package -h -l -p")" -- "$cur") + ;; + *'debug log-level get'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --package -h -p")" -- "$cur") ;; @@ -788,332 +788,340 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level -c -h -l")" -- "$cur") ;; + *'debug thread-dump'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + + *'container restart'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + *'container unpause'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector unpause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug block-traffic'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --destination --help --port -c -h")" -- "$cur") ;; - *'container recreate'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --ignore-current-versions -h")" -- "$cur") + *'run'*'--cluster-cloud') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure")" -- "$cur") ;; - *'connector snippets'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--converter --dlq --help -h")" -- "$cur") + *'topic alter'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'ec2 open'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'connector versions'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'connector status'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'ec2 stop'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") - ;; - - *'topic alter'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'connector resume'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'topic produce'*'--key') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'run'*'--cluster-cloud') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure")" -- "$cur") + *'ec2 stop'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'run'*'--connector-jar') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") + *'ec2 open'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'container resume'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector delete'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector resume'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'connector show-lag'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --interval --max-wait --verbose -c -h -v")" -- "$cur") ;; - *'connector delete'*'-c') + *'connector update'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug java-debug'*'-c') + *'get-docker-compose'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + + *'container resume'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector update'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug java-debug'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector show-lag'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --interval --max-wait --verbose -c -h -v")" -- "$cur") + *'connector snippets'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--converter --dlq --help -h")" -- "$cur") ;; - *'connector versions'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'container recreate'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --ignore-current-versions -h")" -- "$cur") ;; *'repro import'*'--file') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") ;; - *'container kill-all'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'run'*'--connector-zip') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") ;; - *'get-docker-compose'*) + *'container kill-all'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector pause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'connector offsets'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter get get-offsets-request-status reset")" -- "$cur") - ;; - - *'connector restart'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'run'*'--connector-jar') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") ;; *'connector plugins'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help --verbose -h -v")" -- "$cur") ;; - *'repro bootstrap'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") - ;; - - *'repro bootstrap'*'-p') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") + *'debug heap-dump'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector unpause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'get-jmx-metrics'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container unpause'*) + *'debug thread-dump'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'container pause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector offsets'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter get get-offsets-request-status reset")" -- "$cur") ;; - *'debug heap-dump'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'repro bootstrap'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") ;; - *'debug thread-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'repro bootstrap'*'-p') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") ;; - *'container restart'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'run'*'--cluster-name') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") ;; *'run'*'--cluster-type') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "basic standard dedicated")" -- "$cur") ;; - *'run'*'--cluster-name') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") + *'connector unpause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'get-jmx-metrics'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector pause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'topic describe'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'connector restart'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'run'*'--environment') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") + *'container unpause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'connector update'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") + *'container restart'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'config clipboard'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'container pause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug tcp-dump'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic describe'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector-plugin'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h search-jar versions")" -- "$cur") + *'connector delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'container exec'*'-c') + *'container kill'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug java-debug'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help --type -c -h")" -- "$cur") + *'connector update'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") ;; - *'container resume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'connector resume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'container logs'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'container resume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; *'connector stop'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector resume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'config clipboard'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'run'*'--environment') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") + ;; + + *'container exec'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'connector status'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'container kill'*'-c') + *'container logs'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container pause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'debug tcp-dump'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector pause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'debug java-debug'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help --type -c -h")" -- "$cur") ;; - *'debug log-level'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h get set")" -- "$cur") + *'connector-plugin'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h search-jar versions")" -- "$cur") ;; - *'repro bootstrap'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--custom-smt --description --file --help --pipeline -d -f -h")" -- "$cur") + *'connector pause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'debug heap-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") + *'get-jmx-metrics'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --domain --help --open -c -d -h -o")" -- "$cur") ;; - *'topic consume'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'tcp-proxy break'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") + ;; + + *'tcp-proxy delay'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") ;; *'tcp-proxy start'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --delay-service-response --help --hostname --port --service-response-corrupt --skip-automatic-connector-config --throttle-service-response -h")" -- "$cur") ;; + *'debug log-level'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h get set")" -- "$cur") + ;; + *'container ssh'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy delay'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") + *'container ssh'*'-s') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") + ;; + + *'container pause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; *'schema register'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --schema --subject --verbose -h -v")" -- "$cur") ;; - *'schema get-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") + *'debug heap-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") ;; - *'topic produce'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'schema set-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") ;; - *'tcp-proxy break'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") + *'repro bootstrap'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--custom-smt --description --file --help --pipeline -d -f -h")" -- "$cur") ;; - *'get-jmx-metrics'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --domain --help --open -c -d -h -o")" -- "$cur") + *'topic consume'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'schema set-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") + *'topic produce'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'container ssh'*'-s') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") + *'schema get-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; *'update-version'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-jar --connector-tag --connector-zip --help --tag -h")" -- "$cur") ;; - *'connector logs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") - ;; - - *'debug tcp-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --duration --help --port -c -h")" -- "$cur") - ;; - *'topic describe'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") ;; + *'container logs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") + ;; + *'connector stop'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'container exec'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--command --container --help --root --shell -c -h")" -- "$cur") + *'connector logs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") ;; - *'repro import'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") + *'debug tcp-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --duration --help --port -c -h")" -- "$cur") ;; *'container kill'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'container logs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") + *'container exec'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--command --container --help --root --shell -c -h")" -- "$cur") ;; *'topic delete'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'container ssh'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") + *'repro import'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") ;; - *'topic consume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--grep --help --key-subject --max-characters --max-messages --min-expected-messages --plot-latencies-timestamp-field --tail --timeout --topic --value-subject --verbose -h -t -v")" -- "$cur") + *'--output-level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") ;; - *'debug testssl'*) + *'config editor'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'topic produce'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --max-nb-messages-to-generate --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") + *'container ssh'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") + ;; + + *'switch-ccloud'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'topic alter'*'-t') @@ -1124,16 +1132,16 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --permanent --subject --verbose --version -h -v")" -- "$cur") ;; - *'switch-ccloud'*) + *'debug testssl'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'--output-level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") + *'topic consume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--grep --help --key-subject --max-characters --max-messages --min-expected-messages --plot-latencies-timestamp-field --tail --timeout --topic --value-subject --verbose -h -t -v")" -- "$cur") ;; - *'config editor'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'topic produce'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --max-nb-messages-to-generate --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") ;; *'repro export'*) @@ -1156,10 +1164,6 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --skip-delete-schema --topic --verbose -h -t -v")" -- "$cur") ;; - *'topic alter'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") - ;; - *'ec2 start'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; @@ -1168,32 +1172,40 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'schema get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") + *'topic alter'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") + ;; + + *'ec2 create'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance-type --size --suffix -h")" -- "$cur") ;; *'ec2 delete'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'open'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") + *'ec2 open'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; *'ec2 stop'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; + *'schema get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") + ;; + *'topic list'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'ec2 create'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance-type --size --suffix -h")" -- "$cur") + *'open'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") ;; - *'ec2 open'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'connector'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create-or-update delete log-level logs offsets open-ccloud-connector-in-browser open-docs pause plugins restart resume select-config show-config show-config-parameters show-lag snippets status stop unpause update versions")" -- "$cur") ;; *'ec2 start'*) @@ -1204,6 +1216,10 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h change-jdk exec get-ip-addresses get-properties kill kill-all logs pause recreate restart resume set-environment-variables ssh unpause")" -- "$cur") ;; + *'open-docs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") + ;; + *'run'*'--file') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") ;; @@ -1212,22 +1228,14 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h break close-all-connection-with-error close-connection delay get-connections start toggle-accept-connections toggle-reads-client toggle-reads-service toggle-writes-client toggle-writes-service")" -- "$cur") ;; - *'connector'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create-or-update delete log-level logs offsets open-ccloud-connector-in-browser open-docs pause plugins restart resume select-config show-config show-config-parameters show-lag snippets status stop unpause update versions")" -- "$cur") - ;; - - *'open-docs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") + *'ec2 open'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--disable-sync-repro-folder --help --instance -h -i")" -- "$cur") ;; *'run'*'--tag') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") ;; - *'ec2 open'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--disable-sync-repro-folder --help --instance -h -i")" -- "$cur") - ;; - *'ec2 list'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -1240,54 +1248,54 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'re-run'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'config'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h check-repo-version clipboard container-kill-all-before-run editor folder_zip_or_jar open-ccloud-connector-in-browser")" -- "$cur") ;; - *'open'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") + *'status'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'schema'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h delete get get-compatibility get-mode register set-compatibility set-mode")" -- "$cur") + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h delete get get-compatibility get-mode register set-compatibility set-mode set-normalize")" -- "$cur") ;; - *'status'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'open'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") ;; - *'topic'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter consume create delete describe display-consumer-offsets get-number-records list produce set-schema-compatibility")" -- "$cur") + *'re-run'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'run'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") + *'tools'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h install-vscode-extension read-avro-file read-parquet-file")" -- "$cur") ;; *'debug'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h block-traffic enable-remote-debugging flight-recorder generate-diagnostics heap-dump java-debug log-level tcp-dump testssl thread-dump")" -- "$cur") ;; - *'tools'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h install-vscode-extension read-avro-file read-parquet-file")" -- "$cur") - ;; - *'repro'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h bootstrap export import")" -- "$cur") ;; - *'open'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + *'run'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") + ;; + + *'topic'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter consume create delete describe display-consumer-offsets get-number-records list produce set-schema-compatibility")" -- "$cur") ;; *'stop'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; + *'open'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + ;; + *'help'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; diff --git a/scripts/cli/playground b/scripts/cli/playground index f55c2e71ce..21075a08c3 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -67,6 +67,7 @@ playground_usage() { printf " %s 🛡️ Set subject-level compatibility\n" "$(green "schema set-compatibility") " printf " %s 🔏 Get subject-level mode\n" "$(green "schema get-mode") " printf " %s 🔏 Set subject-level mode\n" "$(green "schema set-mode") " + printf " %s 🧽 Set normalize at schema registry level\n" "$(green "schema set-normalize") " printf " %s 🧟 Delete schema\n" "$(green "schema delete") " echo printf "%s\n" "$(bold "TCP Proxy commands:")" @@ -2262,6 +2263,7 @@ playground_schema_usage() { printf " %s 🛡️ Set subject-level compatibility\n" "$(green "set-compatibility")" printf " %s 🔏 Get subject-level mode\n" "$(green "get-mode") " printf " %s 🔏 Set subject-level mode\n" "$(green "set-mode") " + printf " %s 🧽 Set normalize at schema registry level\n" "$(green "set-normalize") " printf " %s 🧟 Delete schema\n" "$(green "delete") " echo @@ -2522,6 +2524,44 @@ playground_schema_set_mode_usage() { fi } +# :command.usage +playground_schema_set_normalize_usage() { + if [[ -n $long_usage ]]; then + printf "playground schema set-normalize\n\n" + printf " 🧽 Set normalize at schema registry level\n \n See\n https://docs.confluent.io/platform/current/schema-registry/fundamentals/serdes-develop/index.html#schema-normalization\n\n" + else + printf "playground schema set-normalize - 🧽 Set normalize at schema registry level\n\n" + fi + + printf "%s\n" "$(bold "== Usage ==")" + printf " playground schema set-normalize [OPTIONS]\n" + printf " playground schema set-normalize --help | -h\n" + echo + + # :command.long_usage + if [[ -n "$long_usage" ]]; then + printf "%s\n" "$(bold "== Options ==")" + + # :command.usage_flags + # :flag.usage + printf " %s\n" "$(magenta "--verbose, -v")" + printf " 🐞 Show command being ran.\n" + echo + + # :flag.usage + printf " %s\n" "$(magenta "--value VALUE (required)")" + printf " true or false\n" + printf " %s\n" "Allowed: true, false" + echo + + # :command.usage_fixed_flags + printf " %s\n" "$(magenta "--help, -h")" + printf " Show this help\n" + echo + + fi +} + # :command.usage playground_schema_delete_usage() { printf "playground schema delete - 🧟 Delete schema\n\n" @@ -4377,7 +4417,7 @@ playground_topic_consume_usage() { # :flag.usage printf " %s\n" "$(magenta "--max-messages MAX-MESSAGES")" - printf " Max number of messages to display (default is 100)\n" + printf " Max number of messages to display (default is 100)\n \n You can use -1 to display all messages\n" printf " %s\n" "Default: 100" echo @@ -18101,6 +18141,42 @@ playground_schema_set_mode_command() { fi } +# :command.function +playground_schema_set_normalize_command() { + # src/commands/schema/set-normalize.sh + value="${args[--value]}" + verbose="${args[--verbose]}" + + get_sr_url_and_security + + log "🧽 Set normalize to $value at schema registry level" + if [[ -n "$verbose" ]] + then + log "🐞 curl command used" + echo "curl $sr_security -s -X PUT -H "Content-Type: application/vnd.schemaregistry.v1+json" --data "{\"normalize\": \"${value}\"}" "${sr_url}/config"" + fi + curl_output=$(curl $sr_security -s -X PUT -H "Content-Type: application/vnd.schemaregistry.v1+json" --data "{\"normalize\": \"${value}\"}" "${sr_url}/config" | jq .) + ret=$? + if [ $ret -eq 0 ] + then + if echo "$curl_output" | jq '. | has("error_code")' 2> /dev/null | grep -q true + + then + error_code=$(echo "$curl_output" | jq -r .error_code) + message=$(echo "$curl_output" | jq -r .message) + logerror "Command failed with error code $error_code" + logerror "$message" + exit 1 + else + normalize=$(echo "$curl_output" | jq -r .normalize) + echo "$normalize" + fi + else + logerror "❌ curl request failed with error code $ret!" + exit 1 + fi +} + # :command.function playground_schema_delete_command() { # src/commands/schema/delete.sh @@ -29994,6 +30070,13 @@ playground_schema_parse_requirements() { shift $# ;; + set-normalize) + action="set-normalize" + shift + playground_schema_set_normalize_parse_requirements "$@" + shift $# + ;; + delete) action="delete" shift @@ -30673,6 +30756,97 @@ playground_schema_set_mode_parse_requirements() { } +# :command.parse_requirements +playground_schema_set_normalize_parse_requirements() { + # :command.fixed_flags_filter + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + --help | -h) + long_usage=yes + playground_schema_set_normalize_usage + exit + ;; + + *) + break + ;; + + esac + done + + # :command.command_filter + action="schema set-normalize" + + # :command.parse_requirements_while + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + # :flag.case + --verbose | -v) + + # :flag.case_no_arg + args['--verbose']=1 + shift + ;; + + # :flag.case + --value) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + args['--value']="$2" + shift + shift + else + printf "%s\n" "--value requires an argument: --value VALUE" >&2 + exit 1 + fi + ;; + + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; + + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + printf "invalid argument: %s\n" "$key" >&2 + exit 1 + + ;; + + esac + done + + # :command.required_flags_filter + if [[ -z ${args['--value']+x} ]]; then + printf "missing required flag: --value VALUE\n" >&2 + exit 1 + fi + + # :command.whitelist_filter + if [[ ${args['--value']:-} ]] && [[ ! ${args['--value']:-} =~ ^(true|false)$ ]]; then + printf "%s\n" "--value must be one of: true, false" >&2 + exit 1 + fi + + # :command.user_filter + filter_error=$(filter_not_mdc_environment) + if [[ -n $filter_error ]]; then + echo "$filter_error" >&2 + exit 1 + fi + + filter_error=$(filter_schema_registry_running) + if [[ -n $filter_error ]]; then + echo "$filter_error" >&2 + exit 1 + fi + +} + # :command.parse_requirements playground_schema_delete_parse_requirements() { # :command.fixed_flags_filter @@ -39182,6 +39356,7 @@ run() { "schema set-compatibility") playground_schema_set_compatibility_command ;; "schema get-mode") playground_schema_get_mode_command ;; "schema set-mode") playground_schema_set_mode_command ;; + "schema set-normalize") playground_schema_set_normalize_command ;; "schema delete") playground_schema_delete_command ;; "tcp-proxy") playground_tcp_proxy_command ;; "tcp-proxy start") playground_tcp_proxy_start_command ;; diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index 7b61e2e0a1..3400b26ed6 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -730,6 +730,31 @@ } ] }, + { + "name": "set-normalize", + "description": "🧽 Set normalize at schema registry level\n \n See https://docs.confluent.io/platform/current/schema-registry/fundamentals/serdes-develop/index.html#schema-normalization\n", + "usage": "playground schema set-normalize [OPTIONS]", + "options": [ + { + "names": [ + "--verbose", + "-v" + ], + "argument": "", + "description": "🐞 Show command being ran.\n" + }, + { + "names": [ + "--value" + ], + "argument": [ + true, + false + ], + "description": "true or false\n\nRequired: ✓ Yes\n\nAllowed values: true, false\n" + } + ] + }, { "name": "delete", "description": "🧟 Delete schema\n", @@ -1718,7 +1743,7 @@ "--max-messages" ], "argument": 100, - "description": "Max number of messages to display (default is 100)\n\nDefault value: 100\n" + "description": "Max number of messages to display (default is 100)\n\nYou can use -1 to display all messages\n\nDefault value: 100\n" }, { "names": [ diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index 7803efbb01..3f047bbe20 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -849,6 +849,30 @@ subcommands: Allowed values: IMPORT, READONLY, READWRITE + - name: set-normalize + description: | + 🧽 Set normalize at schema registry level + + See https://docs.confluent.io/platform/current/schema-registry/fundamentals/serdes-develop/index.html#schema-normalization + usage: playground schema set-normalize [OPTIONS] + options: + - names: + - --verbose + - -v + argument: "" + description: | + 🐞 Show command being ran. + + - names: + - --value + argument: [true, false] + description: | + true or false + + Required: ✓ Yes + + Allowed values: true, false + - name: delete description: | 🧟 Delete schema @@ -1831,6 +1855,8 @@ subcommands: description: | Max number of messages to display (default is 100) + You can use -1 to display all messages + Default value: 100 - names: diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index 2443fb6f43..f2280c265a 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -1295,6 +1295,26 @@ commands: help: |- Schema Registry mode + - name: set-normalize + filters: + - not_mdc_environment + - schema_registry_running + group: Schema + help: |- + 🧽 Set normalize at schema registry level + + See https://docs.confluent.io/platform/current/schema-registry/fundamentals/serdes-develop/index.html#schema-normalization + flags: + - *verbose + - long: --value + arg: value + allowed: + - "true" + - "false" + required: true + help: |- + true or false + - name: delete filters: - not_mdc_environment diff --git a/scripts/cli/src/commands/schema/set-normalize.sh b/scripts/cli/src/commands/schema/set-normalize.sh new file mode 100644 index 0000000000..8f94a9308c --- /dev/null +++ b/scripts/cli/src/commands/schema/set-normalize.sh @@ -0,0 +1,30 @@ +value="${args[--value]}" +verbose="${args[--verbose]}" + +get_sr_url_and_security + +log "🧽 Set normalize to $value at schema registry level" +if [[ -n "$verbose" ]] +then + log "🐞 curl command used" + echo "curl $sr_security -s -X PUT -H "Content-Type: application/vnd.schemaregistry.v1+json" --data "{\"normalize\": \"${value}\"}" "${sr_url}/config"" +fi +curl_output=$(curl $sr_security -s -X PUT -H "Content-Type: application/vnd.schemaregistry.v1+json" --data "{\"normalize\": \"${value}\"}" "${sr_url}/config" | jq .) +ret=$? +if [ $ret -eq 0 ] +then + if echo "$curl_output" | jq '. | has("error_code")' 2> /dev/null | grep -q true + then + error_code=$(echo "$curl_output" | jq -r .error_code) + message=$(echo "$curl_output" | jq -r .message) + logerror "Command failed with error code $error_code" + logerror "$message" + exit 1 + else + normalize=$(echo "$curl_output" | jq -r .normalize) + echo "$normalize" + fi +else + logerror "❌ curl request failed with error code $ret!" + exit 1 +fi \ No newline at end of file From 61ea36be5cb4c636878e4fa8f82acd9da678cded Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 14 Nov 2024 22:35:49 +0100 Subject: [PATCH 047/659] remove symbolic links --- scripts/cli/playground | 18 +++++++++--------- scripts/cli/src/commands/repro/bootstrap.sh | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 21075a08c3..06956f46d5 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -16693,15 +16693,15 @@ playground_repro_bootstrap_command() { cat $repro_test_file | grep -v "#!/bin/bash" >> $tmp_dir/tmp_file mv $tmp_dir/tmp_file $repro_test_file - for file in README.md docker-compose*.yml keyfile.json stop.sh .gitignore sql-datagen - do - if [ -f $file ] - then - cd $repro_dir > /dev/null - ln -sf ../../$dir2/$file . - cd - > /dev/null - fi - done + # for file in README.md docker-compose*.yml keyfile.json stop.sh .gitignore sql-datagen + # do + # if [ -f $file ] + # then + # cd $repro_dir > /dev/null + # ln -sf ../../$dir2/$file . + # cd - > /dev/null + # fi + # done if [ "$producer" != "none" ] then diff --git a/scripts/cli/src/commands/repro/bootstrap.sh b/scripts/cli/src/commands/repro/bootstrap.sh index f27e051dae..ab9e5fb3ca 100644 --- a/scripts/cli/src/commands/repro/bootstrap.sh +++ b/scripts/cli/src/commands/repro/bootstrap.sh @@ -378,15 +378,15 @@ cat $tmp_dir/intro > $tmp_dir/tmp_file cat $repro_test_file | grep -v "#!/bin/bash" >> $tmp_dir/tmp_file mv $tmp_dir/tmp_file $repro_test_file -for file in README.md docker-compose*.yml keyfile.json stop.sh .gitignore sql-datagen -do - if [ -f $file ] - then - cd $repro_dir > /dev/null - ln -sf ../../$dir2/$file . - cd - > /dev/null - fi -done +# for file in README.md docker-compose*.yml keyfile.json stop.sh .gitignore sql-datagen +# do +# if [ -f $file ] +# then +# cd $repro_dir > /dev/null +# ln -sf ../../$dir2/$file . +# cd - > /dev/null +# fi +# done if [ "$producer" != "none" ] then From 256d1c2e4581589946f04df2d59764ee66a13f4c Mon Sep 17 00:00:00 2001 From: Catalin Pop Date: Fri, 15 Nov 2024 16:15:04 -0500 Subject: [PATCH 048/659] added flink download of connectors script to download one or many connectors --- environment/mdc-plaintext/start.sh | 1 + environment/plaintext/docker-compose.yml | 10 +- flink/flink_app_mode/README.md | 2 +- flink/flink_app_mode/docker-compose.yml | 23 +++- flink/flink_app_mode/start.sh | 9 ++ flink/flink_app_mode/stop.sh | 1 + flink/flink_session_mode/README.md | 2 +- flink/flink_session_mode/docker-compose.yml | 21 ++- flink/flink_session_mode/start.sh | 7 + flink/flink_session_mode/stop.sh | 2 + flink/flink_session_sql_mode/README.md | 6 +- .../flink_session_sql_mode/docker-compose.yml | 10 +- flink/flink_session_sql_mode/start.sh | 2 + flink/flink_session_sql_mode/stop.sh | 2 + scripts/cli/confluent-hub-plugin-list.txt | 1 + scripts/cli/playground | 1 + scripts/cli/src/lib/utils_function.sh | 1 + scripts/flink_download_connectors.sh | 130 ++++++++++++++++++ 18 files changed, 211 insertions(+), 20 deletions(-) create mode 100755 scripts/flink_download_connectors.sh diff --git a/environment/mdc-plaintext/start.sh b/environment/mdc-plaintext/start.sh index 4a2d556320..4373a2b951 100755 --- a/environment/mdc-plaintext/start.sh +++ b/environment/mdc-plaintext/start.sh @@ -31,6 +31,7 @@ else log "🐿️ Starting services with Flink..." profile_flink="--profile flink" playground state set flags.ENABLE_FLINK 1 + source ${DIR}/../../scripts/flink_download_connectors.sh fi ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE="" diff --git a/environment/plaintext/docker-compose.yml b/environment/plaintext/docker-compose.yml index fc0bceaa60..87afcd3508 100644 --- a/environment/plaintext/docker-compose.yml +++ b/environment/plaintext/docker-compose.yml @@ -616,7 +616,8 @@ services: - flink ports: - "18081:18081" # Expose port 18081 for REST API and Web UI - command: jobmanager + entrypoint: > + sh -c "$flink_connectors && exec /docker-entrypoint.sh jobmanager" environment: - | FLINK_PROPERTIES= @@ -633,7 +634,8 @@ services: - flink depends_on: - jobmanager - command: taskmanager + entrypoint: > + sh -c "$flink_connectors && exec /docker-entrypoint.sh taskmanager" environment: - | FLINK_PROPERTIES= @@ -649,12 +651,12 @@ services: container_name: sql-client profiles: - flink - depends_on: - jobmanager stdin_open: true tty: true - command: bin/sql-client.sh + entrypoint: > + sh -c "$flink_connectors && exec /docker-entrypoint.sh bin/sql-client.sh" environment: - | FLINK_PROPERTIES= diff --git a/flink/flink_app_mode/README.md b/flink/flink_app_mode/README.md index 490a5ccaf1..5589f6124f 100644 --- a/flink/flink_app_mode/README.md +++ b/flink/flink_app_mode/README.md @@ -1,6 +1,6 @@ # Apache Flink in Application Mode with Docker Compose -This setup runs Apache Flink in **Application Mode** using Docker Compose. If you wish to deploy a application, ensure to specify environment variable: +This setup runs Apache Flink in [**Application Mode**](https://nightlies.apache.org/flink/flink-docs-release-1.20/docs/deployment/resource-providers/standalone/docker/#application-mode-1) using Docker Compose. If you wish to deploy a application, ensure to specify environment variable: ``` export FLINK_JAR_PATH=/path/to/my/file.jar diff --git a/flink/flink_app_mode/docker-compose.yml b/flink/flink_app_mode/docker-compose.yml index f2f1229235..307752c5d9 100644 --- a/flink/flink_app_mode/docker-compose.yml +++ b/flink/flink_app_mode/docker-compose.yml @@ -1,12 +1,27 @@ -version: '3.8' - services: jobmanager: - image: flink:latest - command: jobmanager + image: flink:${FLINK_TAG} + entrypoint: > + sh -c "$flink_connectors && exec /docker-entrypoint.sh jobmanager" ports: - "8081:8081" volumes: - ${FLINK_JAR_PATH}:/opt/flink/job.jar environment: - FLINK_PROPERTIES= + + taskmanager: + image: flink:${FLINK_TAG} + depends_on: + - jobmanager + entrypoint: > + sh -c "$flink_connectors && exec /docker-entrypoint.sh taskmanager " + scale: 1 + volumes: + - ${FLINK_JAR_PATH}:/opt/flink/job.jar + environment: + - | + FLINK_PROPERTIES= + jobmanager.rpc.address: jobmanager + taskmanager.numberOfTaskSlots: 2 + parallelism.default: 2 \ No newline at end of file diff --git a/flink/flink_app_mode/start.sh b/flink/flink_app_mode/start.sh index 0ac6089959..1a894d8418 100755 --- a/flink/flink_app_mode/start.sh +++ b/flink/flink_app_mode/start.sh @@ -4,4 +4,13 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" # loading env variables source ${DIR}/../../scripts/utils.sh +if [ -z "$FLINK_JAR_PATH" ] +then + # Flink variable isn't set + log "❌ FLINK_JAR_PATH is not set, you need to export the variable with a path to the jar file(ex: export FLINK_JAR_PATH=/path/to/my/file.jar)" + exit +fi + +source ${DIR}/../../scripts/flink_download_connectors.sh + docker-compose up -d \ No newline at end of file diff --git a/flink/flink_app_mode/stop.sh b/flink/flink_app_mode/stop.sh index d2aaf929a4..eb1a7c66c6 100755 --- a/flink/flink_app_mode/stop.sh +++ b/flink/flink_app_mode/stop.sh @@ -3,4 +3,5 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh +docker-compose down -v --remove-orphans stop_all "$DIR" diff --git a/flink/flink_session_mode/README.md b/flink/flink_session_mode/README.md index a114539cdc..1ceb994114 100644 --- a/flink/flink_session_mode/README.md +++ b/flink/flink_session_mode/README.md @@ -1,6 +1,6 @@ # Apache Flink in Session Mode with Docker Compose -This setup runs Apache Flink in **Session Mode** using Docker Compose. +This setup runs Apache Flink in [**Session Mode**](https://nightlies.apache.org/flink/flink-docs-release-1.20/docs/deployment/resource-providers/standalone/docker/#session-mode-1) using Docker Compose. ## How to Start diff --git a/flink/flink_session_mode/docker-compose.yml b/flink/flink_session_mode/docker-compose.yml index c168b135a8..0d5f2fae5d 100644 --- a/flink/flink_session_mode/docker-compose.yml +++ b/flink/flink_session_mode/docker-compose.yml @@ -1,15 +1,24 @@ -version: '3.8' - services: jobmanager: image: flink:${FLINK_TAG} - command: jobmanager + entrypoint: > + sh -c "$flink_connectors && exec /docker-entrypoint.sh jobmanager" ports: - "8081:8081" + environment: + - | + FLINK_PROPERTIES= + jobmanager.rpc.address: jobmanager taskmanager: image: flink:${FLINK_TAG} - command: taskmanager - scale: 2 + entrypoint: > + sh -c "$flink_connectors && exec /docker-entrypoint.sh taskmanager" + scale: 1 depends_on: - - jobmanager \ No newline at end of file + - jobmanager + environment: + - | + FLINK_PROPERTIES= + jobmanager.rpc.address: jobmanager + taskmanager.numberOfTaskSlots: 2 \ No newline at end of file diff --git a/flink/flink_session_mode/start.sh b/flink/flink_session_mode/start.sh index 80b5727c14..3f6a696f54 100755 --- a/flink/flink_session_mode/start.sh +++ b/flink/flink_session_mode/start.sh @@ -1,3 +1,10 @@ #!/bin/bash +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +# loading env variables +source ${DIR}/../../scripts/utils.sh + + +source ${DIR}/../../scripts/flink_download_connectors.sh + docker-compose up -d \ No newline at end of file diff --git a/flink/flink_session_mode/stop.sh b/flink/flink_session_mode/stop.sh index 9e39920efa..7962d46338 100755 --- a/flink/flink_session_mode/stop.sh +++ b/flink/flink_session_mode/stop.sh @@ -4,4 +4,6 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" echo "Pops ${DIR}" source ${DIR}/../../scripts/utils.sh +docker-compose down -v --remove-orphans + stop_all "$DIR" \ No newline at end of file diff --git a/flink/flink_session_sql_mode/README.md b/flink/flink_session_sql_mode/README.md index a3b6941a9a..bb2edf4f3d 100644 --- a/flink/flink_session_sql_mode/README.md +++ b/flink/flink_session_sql_mode/README.md @@ -1,12 +1,16 @@ # Apache Flink in Session Mode with SQL Client using Docker Compose -This setup runs Apache Flink in **Session Mode** with the **SQL Client**. +This setup runs Apache Flink in [**Session Mode** with the **SQL Client**](https://nightlies.apache.org/flink/flink-docs-release-1.20/docs/deployment/resource-providers/standalone/docker/#flink-sql-client-with-session-cluster). ## How to attach to SQL client +Run the following command: + ``` docker attach sql-client ``` + When quitting out of the SQL client, the container will stop working. If you wish to restart the SQL Client, simply run: + ``` docker-compose start sql-client ``` diff --git a/flink/flink_session_sql_mode/docker-compose.yml b/flink/flink_session_sql_mode/docker-compose.yml index f8978c5ae4..ba634346da 100644 --- a/flink/flink_session_sql_mode/docker-compose.yml +++ b/flink/flink_session_sql_mode/docker-compose.yml @@ -8,7 +8,8 @@ services: container_name: jobmanager ports: - "8081:8081" - command: jobmanager + entrypoint: > + sh -c "$flink_connectors && exec /docker-entrypoint.sh jobmanager" environment: - | FLINK_PROPERTIES= @@ -21,7 +22,8 @@ services: container_name: taskmanager depends_on: - jobmanager - command: taskmanager + entrypoint: > + sh -c "$flink_connectors && exec /docker-entrypoint.sh taskmanager" environment: - | FLINK_PROPERTIES= @@ -38,7 +40,9 @@ services: - jobmanager stdin_open: true tty: true - command: bin/sql-client.sh + # command: bin/sql-client.sh + entrypoint: > + sh -c "$flink_connectors && exec /docker-entrypoint.sh bin/sql-client.sh" environment: - | FLINK_PROPERTIES= diff --git a/flink/flink_session_sql_mode/start.sh b/flink/flink_session_sql_mode/start.sh index 0ac6089959..8d514a7339 100755 --- a/flink/flink_session_sql_mode/start.sh +++ b/flink/flink_session_sql_mode/start.sh @@ -4,4 +4,6 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" # loading env variables source ${DIR}/../../scripts/utils.sh +source ${DIR}/../../scripts/flink_download_connectors.sh + docker-compose up -d \ No newline at end of file diff --git a/flink/flink_session_sql_mode/stop.sh b/flink/flink_session_sql_mode/stop.sh index e127f27883..92b92d34a0 100755 --- a/flink/flink_session_sql_mode/stop.sh +++ b/flink/flink_session_sql_mode/stop.sh @@ -3,4 +3,6 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh +docker-compose down -v --remove-orphans + stop_all "$DIR" \ No newline at end of file diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index ca3196f910..6f8aca013a 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -128,6 +128,7 @@ hazelcast/kafka-connector hivemq/enterprise-extension ibm/data-replication imply/druid-kafka-indexing-service +imply/imply-native-integration infoviewsystems/kafka-connect-as400 init/kafka-connect-adso init/kafka-connect-odatabusevent diff --git a/scripts/cli/playground b/scripts/cli/playground index 41f3c544ec..2a45a6bcbe 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8539,6 +8539,7 @@ function set_profiles() { log "🐿️ Starting services with Flink" profile_flink="--profile flink" playground state set flags.ENABLE_FLINK 1 + source ${DIR}/../../scripts/flink_download_connectors.sh fi profile_ksqldb_command="" diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 3ab80ab655..d910f7dcb4 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -503,6 +503,7 @@ function set_profiles() { log "🐿️ Starting services with Flink" profile_flink="--profile flink" playground state set flags.ENABLE_FLINK 1 + source ${DIR}/../../scripts/flink_download_connectors.sh fi profile_ksqldb_command="" diff --git a/scripts/flink_download_connectors.sh b/scripts/flink_download_connectors.sh new file mode 100755 index 0000000000..9647eb592a --- /dev/null +++ b/scripts/flink_download_connectors.sh @@ -0,0 +1,130 @@ +#!/bin/bash + +log "❗ Do you need to install any Flink connectors? (yes/no)" +read need_connectors + +if [[ "$need_connectors" != "yes" ]]; then + log "Exiting." + exit 0 +fi + +log "❗ Is it one connector or multiple connectors? (one/multiple)" +read connector_count + +if [[ "$connector_count" == "one" ]]; then + log "Please type one word that's related to the connector name:" + read keyword + keywords=("$keyword") +else + log "Please type multiple words related to the connector names (separated by spaces):" + read -a keywords +fi + +# Function to fetch connector list +get_connectors() { + curl -s https://repo.maven.apache.org/maven2/org/apache/flink/ | awk -F '"' '/href/ {print $2}' | sed 's:/$::' | sort -u +} + +connector_list=$(get_connectors) +selected_connectors=() + +# Loop through each keyword +for keyword in "${keywords[@]}"; do + matches=$(echo "$connector_list" | grep -i "$keyword") + if [[ -z "$matches" ]]; then + log "No connectors found matching '$keyword'." + continue + fi + log "Connectors matching '$keyword':" + i=1 + match_list=() + while IFS= read -r line; do + echo "$i) $line" + match_list+=("$line") + ((i++)) + done <<< "$matches" + + log "Please select connectors by numbers (separated by spaces):" + read selection + IFS=' ' read -r -a selections <<< "$selection" + for sel in "${selections[@]}"; do + if [[ $sel -le ${#match_list[@]} && $sel -ge 1 ]]; then + selected_connector=${match_list[$((sel - 1))]} + selected_connectors+=("$selected_connector") + log "Selected connector: $selected_connector" + else + log "Invalid selection: $sel" + fi + done +done + +connector_urls=() + +# Loop through each selected connector +for connector in "${selected_connectors[@]}"; do + log "Fetching versions for connector: $connector" + connector_url="https://repo.maven.apache.org/maven2/org/apache/flink/$connector/" + versions=$(curl -s "$connector_url" | awk -F '"' '/href/ {print $2}' | sed 's:/$::' | sort -u) + if [[ -z "$versions" ]]; then + log "No versions found for connector '$connector'." + continue + fi + log "Available versions for $connector:" + i=1 + version_list=() + while IFS= read -r version; do + echo "$i) $version" + version_list+=("$version") + ((i++)) + done <<< "$versions" + + log "Please select a version by number for connector $connector:" + read version_selection + if [[ $version_selection -le ${#version_list[@]} && $version_selection -ge 1 ]]; then + selected_version=${version_list[$((version_selection - 1))]} + else + log "Invalid selection. Skipping connector $connector." + continue + fi + + # Fetch jar files for the selected version + jar_url="$connector_url$selected_version/" + log "Fetching jar files for $connector version $selected_version" + jar_files=$(curl -s "$jar_url" | awk -F '"' '/href/ {print $2}' | grep -E '\.jar$' | sort -u) + if [[ -z "$jar_files" ]]; then + log "No jar files found for $connector version $selected_version." + continue + fi + log "Available jar files for $connector version $selected_version:" + i=1 + jar_list=() + while IFS= read -r jar; do + echo "$i) $jar" + jar_list+=("$jar") + ((i++)) + done <<< "$jar_files" + + log "❗ Please select jar files by numbers (separated by spaces), or type ⭐'complete'⭐ to finish selection:" + read jar_selection + if [[ "$jar_selection" == "complete" ]]; then + continue + fi + IFS=' ' read -r -a jar_selections <<< "$jar_selection" + for js in "${jar_selections[@]}"; do + if [[ $js -le ${#jar_list[@]} && $js -ge 1 ]]; then + selected_jar=${jar_list[$((js - 1))]} + full_url="$jar_url$selected_jar" + connector_urls+=("$full_url") + log "Selected jar file: $selected_jar" + else + log "Invalid selection: $js" + fi + done +done + +# Set the environment variable 'connectors' +flink_connectors="wget -P /opt/flink/lib ${connector_urls[*]}" +export flink_connectors + +log "Environment variable 'flink_connectors' set with the following URLs which will be downloaded for the containers:" +log "$flink_connectors" \ No newline at end of file From 840ce33af6ae2ec0a448a9018069a83835a72bc0 Mon Sep 17 00:00:00 2001 From: Catalin Pop Date: Fri, 15 Nov 2024 16:33:19 -0500 Subject: [PATCH 049/659] fixed so if you say no to connectors it now works --- environment/plaintext/docker-compose.yml | 6 +- flink/flink_app_mode/docker-compose.yml | 4 +- flink/flink_session_mode/docker-compose.yml | 4 +- .../flink_session_sql_mode/docker-compose.yml | 6 +- scripts/flink_download_connectors.sh | 229 +++++++++--------- 5 files changed, 127 insertions(+), 122 deletions(-) diff --git a/environment/plaintext/docker-compose.yml b/environment/plaintext/docker-compose.yml index 87afcd3508..65f11168e8 100644 --- a/environment/plaintext/docker-compose.yml +++ b/environment/plaintext/docker-compose.yml @@ -617,7 +617,7 @@ services: ports: - "18081:18081" # Expose port 18081 for REST API and Web UI entrypoint: > - sh -c "$flink_connectors && exec /docker-entrypoint.sh jobmanager" + sh -c "$flink_connectors exec /docker-entrypoint.sh jobmanager" environment: - | FLINK_PROPERTIES= @@ -635,7 +635,7 @@ services: depends_on: - jobmanager entrypoint: > - sh -c "$flink_connectors && exec /docker-entrypoint.sh taskmanager" + sh -c "$flink_connectors exec /docker-entrypoint.sh taskmanager" environment: - | FLINK_PROPERTIES= @@ -656,7 +656,7 @@ services: stdin_open: true tty: true entrypoint: > - sh -c "$flink_connectors && exec /docker-entrypoint.sh bin/sql-client.sh" + sh -c "$flink_connectors exec /docker-entrypoint.sh bin/sql-client.sh" environment: - | FLINK_PROPERTIES= diff --git a/flink/flink_app_mode/docker-compose.yml b/flink/flink_app_mode/docker-compose.yml index 307752c5d9..7e8c0160c6 100644 --- a/flink/flink_app_mode/docker-compose.yml +++ b/flink/flink_app_mode/docker-compose.yml @@ -2,7 +2,7 @@ services: jobmanager: image: flink:${FLINK_TAG} entrypoint: > - sh -c "$flink_connectors && exec /docker-entrypoint.sh jobmanager" + sh -c "$flink_connectors exec /docker-entrypoint.sh jobmanager" ports: - "8081:8081" volumes: @@ -15,7 +15,7 @@ services: depends_on: - jobmanager entrypoint: > - sh -c "$flink_connectors && exec /docker-entrypoint.sh taskmanager " + sh -c "$flink_connectors exec /docker-entrypoint.sh taskmanager " scale: 1 volumes: - ${FLINK_JAR_PATH}:/opt/flink/job.jar diff --git a/flink/flink_session_mode/docker-compose.yml b/flink/flink_session_mode/docker-compose.yml index 0d5f2fae5d..5075dcb66e 100644 --- a/flink/flink_session_mode/docker-compose.yml +++ b/flink/flink_session_mode/docker-compose.yml @@ -2,7 +2,7 @@ services: jobmanager: image: flink:${FLINK_TAG} entrypoint: > - sh -c "$flink_connectors && exec /docker-entrypoint.sh jobmanager" + sh -c "$flink_connectors exec /docker-entrypoint.sh jobmanager" ports: - "8081:8081" environment: @@ -13,7 +13,7 @@ services: taskmanager: image: flink:${FLINK_TAG} entrypoint: > - sh -c "$flink_connectors && exec /docker-entrypoint.sh taskmanager" + sh -c "$flink_connectors exec /docker-entrypoint.sh taskmanager" scale: 1 depends_on: - jobmanager diff --git a/flink/flink_session_sql_mode/docker-compose.yml b/flink/flink_session_sql_mode/docker-compose.yml index ba634346da..8cfda4dfda 100644 --- a/flink/flink_session_sql_mode/docker-compose.yml +++ b/flink/flink_session_sql_mode/docker-compose.yml @@ -9,7 +9,7 @@ services: ports: - "8081:8081" entrypoint: > - sh -c "$flink_connectors && exec /docker-entrypoint.sh jobmanager" + sh -c "$flink_connectors exec /docker-entrypoint.sh jobmanager" environment: - | FLINK_PROPERTIES= @@ -23,7 +23,7 @@ services: depends_on: - jobmanager entrypoint: > - sh -c "$flink_connectors && exec /docker-entrypoint.sh taskmanager" + sh -c "$flink_connectors exec /docker-entrypoint.sh taskmanager" environment: - | FLINK_PROPERTIES= @@ -42,7 +42,7 @@ services: tty: true # command: bin/sql-client.sh entrypoint: > - sh -c "$flink_connectors && exec /docker-entrypoint.sh bin/sql-client.sh" + sh -c "$flink_connectors exec /docker-entrypoint.sh bin/sql-client.sh" environment: - | FLINK_PROPERTIES= diff --git a/scripts/flink_download_connectors.sh b/scripts/flink_download_connectors.sh index 9647eb592a..03633390d1 100755 --- a/scripts/flink_download_connectors.sh +++ b/scripts/flink_download_connectors.sh @@ -1,130 +1,135 @@ #!/bin/bash +log() { + echo "$@" +} + log "❗ Do you need to install any Flink connectors? (yes/no)" read need_connectors if [[ "$need_connectors" != "yes" ]]; then - log "Exiting." - exit 0 -fi - -log "❗ Is it one connector or multiple connectors? (one/multiple)" -read connector_count - -if [[ "$connector_count" == "one" ]]; then - log "Please type one word that's related to the connector name:" - read keyword - keywords=("$keyword") + log "Skipping connector installation steps." else - log "Please type multiple words related to the connector names (separated by spaces):" - read -a keywords -fi + log "❗ Is it one connector or multiple connectors? (one/multiple)" + read connector_count -# Function to fetch connector list -get_connectors() { - curl -s https://repo.maven.apache.org/maven2/org/apache/flink/ | awk -F '"' '/href/ {print $2}' | sed 's:/$::' | sort -u -} + if [[ "$connector_count" == "one" ]]; then + log "Please type one word that's related to the connector name:" + read keyword + keywords=("$keyword") + else + log "Please type multiple words related to the connector names (separated by spaces):" + read -a keywords + fi -connector_list=$(get_connectors) -selected_connectors=() + # Function to fetch connector list + get_connectors() { + curl -s https://repo.maven.apache.org/maven2/org/apache/flink/ | awk -F '"' '/href/ {print $2}' | sed 's:/$::' | sort -u + } -# Loop through each keyword -for keyword in "${keywords[@]}"; do - matches=$(echo "$connector_list" | grep -i "$keyword") - if [[ -z "$matches" ]]; then - log "No connectors found matching '$keyword'." - continue - fi - log "Connectors matching '$keyword':" - i=1 - match_list=() - while IFS= read -r line; do - echo "$i) $line" - match_list+=("$line") - ((i++)) - done <<< "$matches" - - log "Please select connectors by numbers (separated by spaces):" - read selection - IFS=' ' read -r -a selections <<< "$selection" - for sel in "${selections[@]}"; do - if [[ $sel -le ${#match_list[@]} && $sel -ge 1 ]]; then - selected_connector=${match_list[$((sel - 1))]} - selected_connectors+=("$selected_connector") - log "Selected connector: $selected_connector" - else - log "Invalid selection: $sel" + connector_list=$(get_connectors) + selected_connectors=() + + # Loop through each keyword + for keyword in "${keywords[@]}"; do + matches=$(echo "$connector_list" | grep -i "$keyword") + if [[ -z "$matches" ]]; then + log "No connectors found matching '$keyword'." + continue fi + log "Connectors matching '$keyword':" + i=1 + match_list=() + while IFS= read -r line; do + echo "$i) $line" + match_list+=("$line") + ((i++)) + done <<< "$matches" + + log "Please select connectors by numbers (separated by spaces):" + read selection + IFS=' ' read -r -a selections <<< "$selection" + for sel in "${selections[@]}"; do + if [[ $sel -le ${#match_list[@]} && $sel -ge 1 ]]; then + selected_connector=${match_list[$((sel - 1))]} + selected_connectors+=("$selected_connector") + log "Selected connector: $selected_connector" + else + log "Invalid selection: $sel" + fi + done done -done - -connector_urls=() - -# Loop through each selected connector -for connector in "${selected_connectors[@]}"; do - log "Fetching versions for connector: $connector" - connector_url="https://repo.maven.apache.org/maven2/org/apache/flink/$connector/" - versions=$(curl -s "$connector_url" | awk -F '"' '/href/ {print $2}' | sed 's:/$::' | sort -u) - if [[ -z "$versions" ]]; then - log "No versions found for connector '$connector'." - continue - fi - log "Available versions for $connector:" - i=1 - version_list=() - while IFS= read -r version; do - echo "$i) $version" - version_list+=("$version") - ((i++)) - done <<< "$versions" - - log "Please select a version by number for connector $connector:" - read version_selection - if [[ $version_selection -le ${#version_list[@]} && $version_selection -ge 1 ]]; then - selected_version=${version_list[$((version_selection - 1))]} - else - log "Invalid selection. Skipping connector $connector." - continue - fi - # Fetch jar files for the selected version - jar_url="$connector_url$selected_version/" - log "Fetching jar files for $connector version $selected_version" - jar_files=$(curl -s "$jar_url" | awk -F '"' '/href/ {print $2}' | grep -E '\.jar$' | sort -u) - if [[ -z "$jar_files" ]]; then - log "No jar files found for $connector version $selected_version." - continue - fi - log "Available jar files for $connector version $selected_version:" - i=1 - jar_list=() - while IFS= read -r jar; do - echo "$i) $jar" - jar_list+=("$jar") - ((i++)) - done <<< "$jar_files" - - log "❗ Please select jar files by numbers (separated by spaces), or type ⭐'complete'⭐ to finish selection:" - read jar_selection - if [[ "$jar_selection" == "complete" ]]; then - continue - fi - IFS=' ' read -r -a jar_selections <<< "$jar_selection" - for js in "${jar_selections[@]}"; do - if [[ $js -le ${#jar_list[@]} && $js -ge 1 ]]; then - selected_jar=${jar_list[$((js - 1))]} - full_url="$jar_url$selected_jar" - connector_urls+=("$full_url") - log "Selected jar file: $selected_jar" + connector_urls=() + + # Loop through each selected connector + for connector in "${selected_connectors[@]}"; do + log "Fetching versions for connector: $connector" + connector_url="https://repo.maven.apache.org/maven2/org/apache/flink/$connector/" + versions=$(curl -s "$connector_url" | awk -F '"' '/href/ {print $2}' | sed 's:/$::' | sort -u) + if [[ -z "$versions" ]]; then + log "No versions found for connector '$connector'." + continue + fi + log "Available versions for $connector:" + i=1 + version_list=() + while IFS= read -r version; do + echo "$i) $version" + version_list+=("$version") + ((i++)) + done <<< "$versions" + + log "Please select a version by number for connector $connector:" + read version_selection + if [[ $version_selection -le ${#version_list[@]} && $version_selection -ge 1 ]]; then + selected_version=${version_list[$((version_selection - 1))]} else - log "Invalid selection: $js" + log "Invalid selection. Skipping connector $connector." + continue fi + + # Fetch jar files for the selected version + jar_url="$connector_url$selected_version/" + log "Fetching jar files for $connector version $selected_version" + jar_files=$(curl -s "$jar_url" | awk -F '"' '/href/ {print $2}' | grep -E '\.jar$' | sort -u) + if [[ -z "$jar_files" ]]; then + log "No jar files found for $connector version $selected_version." + continue + fi + log "Available jar files for $connector version $selected_version:" + i=1 + jar_list=() + while IFS= read -r jar; do + echo "$i) $jar" + jar_list+=("$jar") + ((i++)) + done <<< "$jar_files" + + log "❗ Please select jar files by numbers (separated by spaces), or type ⭐'complete'⭐ to finish selection:" + read jar_selection + if [[ "$jar_selection" == "complete" ]]; then + continue + fi + IFS=' ' read -r -a jar_selections <<< "$jar_selection" + for js in "${jar_selections[@]}"; do + if [[ $js -le ${#jar_list[@]} && $js -ge 1 ]]; then + selected_jar=${jar_list[$((js - 1))]} + full_url="$jar_url$selected_jar" + connector_urls+=("$full_url") + log "Selected jar file: $selected_jar" + else + log "Invalid selection: $js" + fi + done done -done -# Set the environment variable 'connectors' -flink_connectors="wget -P /opt/flink/lib ${connector_urls[*]}" -export flink_connectors + # Set the environment variable 'connectors' + flink_connectors="wget -P /opt/flink/lib ${connector_urls[*]} && " + export flink_connectors + + log "Environment variable 'flink_connectors' set with the following URLs which will be downloaded for the containers:" + log "$flink_connectors" +fi -log "Environment variable 'flink_connectors' set with the following URLs which will be downloaded for the containers:" -log "$flink_connectors" \ No newline at end of file +log "Script completed." \ No newline at end of file From a981802118e4701f6448ecca9f1ffcc180778f4e Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 18 Nov 2024 13:50:35 +0100 Subject: [PATCH 050/659] fix --- scripts/cli/src/commands/debug/heap-dump.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cli/src/commands/debug/heap-dump.sh b/scripts/cli/src/commands/debug/heap-dump.sh index 441d5c71d3..765503a136 100644 --- a/scripts/cli/src/commands/debug/heap-dump.sh +++ b/scripts/cli/src/commands/debug/heap-dump.sh @@ -37,7 +37,7 @@ else docker exec $container jmap -dump:live,format=b,file=/tmp/${filename} 1 else log "🎯 Taking heap dump (without live option) on container ${container}" - docker exec $container jmap -dump:live,format=b,file=/tmp/${filename} 1 + docker exec $container jmap -dump:format=b,file=/tmp/${filename} 1 fi if [ $? -eq 0 ] then From 2635170ad76af02926237986b7582f8d47380c3f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 18 Nov 2024 13:50:43 +0100 Subject: [PATCH 051/659] update --- scripts/cli/confluent-hub-plugin-list.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index ca3196f910..6f8aca013a 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -128,6 +128,7 @@ hazelcast/kafka-connector hivemq/enterprise-extension ibm/data-replication imply/druid-kafka-indexing-service +imply/imply-native-integration infoviewsystems/kafka-connect-as400 init/kafka-connect-adso init/kafka-connect-odatabusevent From f0b01eb0800939d70c58b024bd08df86425b6b10 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 18 Nov 2024 16:27:43 +0100 Subject: [PATCH 052/659] wip --- scripts/cli/confluent-kafka-region-list.txt | 99 +++++++++++++++++++++ scripts/cli/playground | 5 +- scripts/cli/src/commands/run.sh | 33 +++++++ 3 files changed, 134 insertions(+), 3 deletions(-) diff --git a/scripts/cli/confluent-kafka-region-list.txt b/scripts/cli/confluent-kafka-region-list.txt index e69de29bb2..518e686afa 100644 --- a/scripts/cli/confluent-kafka-region-list.txt +++ b/scripts/cli/confluent-kafka-region-list.txt @@ -0,0 +1,99 @@ +Name/Region +Bahrain(me-south-1)/me-south-1 +Belgium(europe-west1)/europe-west1 +Calgary(ca-west-1)/ca-west-1 +Canada(ca-central-1)/ca-central-1 +CapeTown(af-south-1)/af-south-1 +Dallas(us-south1)/us-south1 +Dammam(me-central2)/me-central2 +Delhi(asia-south2)/asia-south2 +Doha(me-central1)/me-central1 +Doha(qatarcentral)/qatarcentral +Dubai(uaenorth)/uaenorth +Finland(europe-north1)/europe-north1 +Frankfurt(eu-central-1)/eu-central-1 +Frankfurt(europe-west3)/europe-west3 +Frankfurt(germanywestcentral)/germanywestcentral +Gävle(swedencentral)/swedencentral +HongKong(ap-east-1)/ap-east-1 +HongKong(asia-east2)/asia-east2 +HongKong(eastasia)/eastasia +Hyderabad(ap-south-2)/ap-south-2 +Iowa(centralus)/centralus +Iowa(us-central1)/us-central1 +Ireland(eu-west-1)/eu-west-1 +Ireland(northeurope)/northeurope +Jakarta(ap-southeast-3)/ap-southeast-3 +Jakarta(asia-southeast2)/asia-southeast2 +Johannesburg/southafricanorth +(southafricanorth)/ +LasVegas(us-west4)/us-west4 +London(eu-west-2)/eu-west-2 +London(europe-west2)/europe-west2 +London(uksouth)/uksouth +LosAngeles(us-west2)/us-west2 +Madrid(europe-southwest1)/europe-southwest1 +Melbourne(ap-southeast-4)/ap-southeast-4 +Melbourne/australia-southeast2 +(australia-southeast2)/ +MexicoCentral(mexicocentral)/mexicocentral +Milan(eu-south-1)/eu-south-1 +Milan(europe-west8)/europe-west8 +Milan(italynorth)/italynorth +Montreal/northamerica-northeast1 +(northamerica-northeast1)/ +Mumbai(ap-south-1)/ap-south-1 +Mumbai(asia-south1)/asia-south1 +N.Virginia(us-east-1)/us-east-1 +N.Virginia(us-east4)/us-east4 +Netherlands(europe-west4)/europe-west4 +Netherlands(westeurope)/westeurope +NewSouthWales/australiaeast +(australiaeast)/ +Ohio(us-east-2)/us-east-2 +Oregon(us-west-2)/us-west-2 +Oregon(us-west1)/us-west1 +Osaka(ap-northeast-3)/ap-northeast-3 +Osaka(asia-northeast2)/asia-northeast2 +Oslo(norwayeast)/norwayeast +Paris(eu-west-3)/eu-west-3 +Paris(europe-west9)/europe-west9 +Paris(francecentral)/francecentral +Phoenix(westus3)/westus3 +Pune(centralindia)/centralindia +S.Carolina(us-east1)/us-east1 +SaltLakeCity(us-west3)/us-west3 +Santiago(southamerica-west1)/southamerica-west1 +SaoPaulo(southamerica-east1)/southamerica-east1 +SaoPaulostate(brazilsouth)/brazilsouth +Seoul(ap-northeast-2)/ap-northeast-2 +Seoul(asia-northeast3)/asia-northeast3 +Seoul(koreacentral)/koreacentral +Singapore(ap-southeast-1)/ap-southeast-1 +Singapore(asia-southeast1)/asia-southeast1 +Singapore(southeastasia)/southeastasia +Spain(eu-south-2)/eu-south-2 +Spain(spaincentral)/spaincentral +Stockholm(eu-north-1)/eu-north-1 +Sydney(ap-southeast-2)/ap-southeast-2 +Sydney(australia-southeast1)/australia-southeast1 +SãoPaulo(sa-east-1)/sa-east-1 +Taiwan(asia-east1)/asia-east1 +TelAviv(il-central-1)/il-central-1 +TelAviv(me-west1)/me-west1 +Texas(southcentralus)/southcentralus +Tokyo(ap-northeast-1)/ap-northeast-1 +Tokyo(asia-northeast1)/asia-northeast1 +Tokyo(japaneast)/japaneast +Toronto(canadacentral)/canadacentral +Toronto/northamerica-northeast2 +(northamerica-northeast2)/ +Turin(europe-west12)/europe-west12 +UAE(me-central-1)/me-central-1 +Virginia(eastus)/eastus +Virginia(eastus2)/eastus2 +Warsaw(europe-central2)/europe-central2 +Washington(westus2)/westus2 +Zurich(eu-central-2)/eu-central-2 +Zurich(europe-west6)/europe-west6 +Zurich(switzerlandnorth)/switzerlandnorth diff --git a/scripts/cli/playground b/scripts/cli/playground index 58c5399d07..3af1dd12f5 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8571,7 +8571,7 @@ function set_profiles() { # Check if ENABLE_FLINK is set to true profile_flink="" - if [ -z "$ENABLE_FLINK" ] + if [ -z "$ENABLE_FLINK" ] then log "🛑 Starting services without Flink" playground state del flags.ENABLE_FLINK @@ -14338,7 +14338,6 @@ playground_run_command() { unset 'options[29]' fi - missing_env="" declare -a missing_env_list=() @@ -18966,7 +18965,7 @@ playground_debug_heap_dump_command() { docker exec $container jmap -dump:live,format=b,file=/tmp/${filename} 1 else log "🎯 Taking heap dump (without live option) on container ${container}" - docker exec $container jmap -dump:live,format=b,file=/tmp/${filename} 1 + docker exec $container jmap -dump:format=b,file=/tmp/${filename} 1 fi if [ $? -eq 0 ] then diff --git a/scripts/cli/src/commands/run.sh b/scripts/cli/src/commands/run.sh index 65d75c4178..7fae8b0c2e 100644 --- a/scripts/cli/src/commands/run.sh +++ b/scripts/cli/src/commands/run.sh @@ -215,6 +215,12 @@ then export ENABLE_CONTROL_CENTER=true fi +if [[ -n "$enable_flink" ]] +then + array_flag_list+=("--enable-flink") + export ENABLE_FLINK=true +fi + if [[ -n "$enable_conduktor" ]] then array_flag_list+=("--enable-conduktor") @@ -806,6 +812,12 @@ then else unset 'options[28]' fi + if [ ! -z $ENABLE_FLINK ] + then + unset 'options[20]' + else + unset 'options[29]' + fi missing_env="" declare -a missing_env_list=() @@ -1015,6 +1027,19 @@ then interactive_enable_c3="" fi + if [[ $res == *"$MENU_ENABLE_FL"* ]] + then + array_flag_list+=("--enable-flink") + export ENABLE_FLINK=true + interactive_enable_flink="true" + fi + if [[ $res == *"$MENU_DISABLE_FL"* ]] + then + array_flag_list=("${array_flag_list[@]/"--enable-flink"}") + unset ENABLE_FLINK + interactive_enable_flink="" + fi + if [[ $res == *"$MENU_ENABLE_RP"* ]] then array_flag_list+=("--enable-rest-proxy") @@ -1312,6 +1337,14 @@ then fi fi + if [ "$interactive_enable_flink" == "true" ] + then + if [[ -n "$force_interactive_repro" ]] + then + force_enable --enable-flink ENABLE_FLINK + fi + fi + if [ "$interactive_enable_conduktor" == "true" ] then if [[ -n "$force_interactive_repro" ]] From 6935a853d9cc48f765360204ac33afa07ed7cc66 Mon Sep 17 00:00:00 2001 From: Catalin Pop Date: Mon, 18 Nov 2024 15:55:50 -0500 Subject: [PATCH 053/659] added if statement in case there are no connectors selected --- scripts/flink_download_connectors.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/flink_download_connectors.sh b/scripts/flink_download_connectors.sh index 03633390d1..bf5cde2f73 100755 --- a/scripts/flink_download_connectors.sh +++ b/scripts/flink_download_connectors.sh @@ -125,7 +125,11 @@ else done # Set the environment variable 'connectors' - flink_connectors="wget -P /opt/flink/lib ${connector_urls[*]} && " + if [ -z "${connector_urls[*]}" ]; then + flink_connectors=" " + else + flink_connectors="wget -P /opt/flink/lib ${connector_urls[*]} && " + fi export flink_connectors log "Environment variable 'flink_connectors' set with the following URLs which will be downloaded for the containers:" From 095b2912d781463914137a0520e33e90d7604400 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 19 Nov 2024 12:23:52 +0100 Subject: [PATCH 054/659] set back ln --- scripts/cli/playground | 19 ++++++++++--------- scripts/cli/src/commands/repro/bootstrap.sh | 18 +++++++++--------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 3af1dd12f5..d87424a906 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8572,6 +8572,7 @@ function set_profiles() { # Check if ENABLE_FLINK is set to true profile_flink="" if [ -z "$ENABLE_FLINK" ] + then log "🛑 Starting services without Flink" playground state del flags.ENABLE_FLINK @@ -16739,15 +16740,15 @@ playground_repro_bootstrap_command() { cat $repro_test_file | grep -v "#!/bin/bash" >> $tmp_dir/tmp_file mv $tmp_dir/tmp_file $repro_test_file - # for file in README.md docker-compose*.yml keyfile.json stop.sh .gitignore sql-datagen - # do - # if [ -f $file ] - # then - # cd $repro_dir > /dev/null - # ln -sf ../../$dir2/$file . - # cd - > /dev/null - # fi - # done + for file in README.md docker-compose*.yml keyfile.json stop.sh .gitignore sql-datagen + do + if [ -f $file ] + then + cd $repro_dir > /dev/null + ln -sf ../../$dir2/$file . + cd - > /dev/null + fi + done if [ "$producer" != "none" ] then diff --git a/scripts/cli/src/commands/repro/bootstrap.sh b/scripts/cli/src/commands/repro/bootstrap.sh index ab9e5fb3ca..f27e051dae 100644 --- a/scripts/cli/src/commands/repro/bootstrap.sh +++ b/scripts/cli/src/commands/repro/bootstrap.sh @@ -378,15 +378,15 @@ cat $tmp_dir/intro > $tmp_dir/tmp_file cat $repro_test_file | grep -v "#!/bin/bash" >> $tmp_dir/tmp_file mv $tmp_dir/tmp_file $repro_test_file -# for file in README.md docker-compose*.yml keyfile.json stop.sh .gitignore sql-datagen -# do -# if [ -f $file ] -# then -# cd $repro_dir > /dev/null -# ln -sf ../../$dir2/$file . -# cd - > /dev/null -# fi -# done +for file in README.md docker-compose*.yml keyfile.json stop.sh .gitignore sql-datagen +do + if [ -f $file ] + then + cd $repro_dir > /dev/null + ln -sf ../../$dir2/$file . + cd - > /dev/null + fi +done if [ "$producer" != "none" ] then From a329b742a8d2a4f4bb140593daa5ed26bc1a4db5 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 21 Nov 2024 09:46:23 +0100 Subject: [PATCH 055/659] wip --- scripts/cli/confluent-hub-plugin-list.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index 6f8aca013a..2874ce6c95 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -81,6 +81,7 @@ confluentinc/kafka-connect-mqtt confluentinc/kafka-connect-netezza confluentinc/kafka-connect-omnisci confluentinc/kafka-connect-oracle-cdc +confluentinc/kafka-connect-oracle-xstream-cdc-source confluentinc/kafka-connect-pagerduty confluentinc/kafka-connect-pinecone-sink confluentinc/kafka-connect-pivotal-gemfire From 52c21030406e286c7e7f85bfaa51fed6408e0334 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 21 Nov 2024 09:46:46 +0100 Subject: [PATCH 056/659] #6005 --- scripts/cli/playground | 6 +++--- scripts/cli/src/commands/connector/create-or-update.sh | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index d87424a906..d30722c56d 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -24488,7 +24488,7 @@ playground_connector_create_or_update_command() { add_connector_config_based_on_environment "$environment" "$json_content" fi # add mandatory name field - new_json_content=$(echo $json_content | jq ". + {\"name\": \"$connector\"}") + new_json_content=$(echo "$json_content" | jq ". + {\"name\": \"$connector\"}") echo "$new_json_content" > $new_json_file handle_onprem_connect_rest_api "curl $security -s -X PUT -H \"Content-Type: application/json\" --data @$new_json_file $connect_url/connector-plugins/$connector_class/config/validate" @@ -24591,7 +24591,7 @@ then log "📍 creating $connector_type connector $connector with offsets: $offsets" # add mandatory name field - new_json_content=$(echo $json_content | jq -c ". + {\"name\": \"$connector\"}") + new_json_content=$(echo "$json_content" | jq -c ". + {\"name\": \"$connector\"}") sed -e "s|:CONNECTOR_NAME:|$connector|g" \ -e "s|:CONNECTOR_CONFIG:|$new_json_content|g" \ @@ -24626,7 +24626,7 @@ else log "🪵 creating $connector_type connector $connector with --initial-state: $initial_state" # add mandatory name field - new_json_content=$(echo $json_content | jq -c ". + {\"name\": \"$connector\"}") + new_json_content=$(echo "$json_content" | jq -c ". + {\"name\": \"$connector\"}") sed -e "s|:CONNECTOR_NAME:|$connector|g" \ -e "s|:CONNECTOR_CONFIG:|$new_json_content|g" \ diff --git a/scripts/cli/src/commands/connector/create-or-update.sh b/scripts/cli/src/commands/connector/create-or-update.sh index 5953bfc99c..3eb9475cae 100644 --- a/scripts/cli/src/commands/connector/create-or-update.sh +++ b/scripts/cli/src/commands/connector/create-or-update.sh @@ -139,7 +139,7 @@ then add_connector_config_based_on_environment "$environment" "$json_content" fi # add mandatory name field - new_json_content=$(echo $json_content | jq ". + {\"name\": \"$connector\"}") + new_json_content=$(echo "$json_content" | jq ". + {\"name\": \"$connector\"}") echo "$new_json_content" > $new_json_file handle_onprem_connect_rest_api "curl $security -s -X PUT -H \"Content-Type: application/json\" --data @$new_json_file $connect_url/connector-plugins/$connector_class/config/validate" @@ -241,7 +241,7 @@ then then log "📍 creating $connector_type connector $connector with offsets: $offsets" # add mandatory name field - new_json_content=$(echo $json_content | jq -c ". + {\"name\": \"$connector\"}") + new_json_content=$(echo "$json_content" | jq -c ". + {\"name\": \"$connector\"}") sed -e "s|:CONNECTOR_NAME:|$connector|g" \ -e "s|:CONNECTOR_CONFIG:|$new_json_content|g" \ @@ -275,7 +275,7 @@ else then log "🪵 creating $connector_type connector $connector with --initial-state: $initial_state" # add mandatory name field - new_json_content=$(echo $json_content | jq -c ". + {\"name\": \"$connector\"}") + new_json_content=$(echo "$json_content" | jq -c ". + {\"name\": \"$connector\"}") sed -e "s|:CONNECTOR_NAME:|$connector|g" \ -e "s|:CONNECTOR_CONFIG:|$new_json_content|g" \ From 1ccf267160e0267927d785b10f689717efa8e88c Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 22 Nov 2024 10:20:03 +0100 Subject: [PATCH 057/659] fix --- scripts/cli/playground | 6 +++--- scripts/cli/src/commands/connector/versions.sh | 2 +- scripts/cli/src/commands/update-version.sh | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index d30722c56d..882660a62b 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -15311,7 +15311,7 @@ playground_update_version_command() { docker_compose_file_available=0 fi - current_tag=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d ":" -f 2) + current_tag=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) if [ "$current_tag" == "" ] then @@ -15676,7 +15676,7 @@ playground_update_version_command() { IFS=' ' flag_list="${array_flag_list[*]}" if [[ -n "$tag" ]] then - current_tag=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d ":" -f 2) + current_tag=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) if [ "$current_tag" == "" ] then @@ -22881,7 +22881,7 @@ playground_connector_versions_command() { logwarn "❌ skipping as it is not an example with connector, but --connector-tag is set" exit 1 else - current_tag=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d ":" -f 2) + current_tag=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) log "🎯 Version currently used for confluent platform" echo "$current_tag" diff --git a/scripts/cli/src/commands/connector/versions.sh b/scripts/cli/src/commands/connector/versions.sh index e7d205b0e0..3e29de3fbb 100644 --- a/scripts/cli/src/commands/connector/versions.sh +++ b/scripts/cli/src/commands/connector/versions.sh @@ -18,7 +18,7 @@ then logwarn "❌ skipping as it is not an example with connector, but --connector-tag is set" exit 1 else - current_tag=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d ":" -f 2) + current_tag=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) log "🎯 Version currently used for confluent platform" echo "$current_tag" diff --git a/scripts/cli/src/commands/update-version.sh b/scripts/cli/src/commands/update-version.sh index a941000754..8a2e6b3882 100644 --- a/scripts/cli/src/commands/update-version.sh +++ b/scripts/cli/src/commands/update-version.sh @@ -22,7 +22,7 @@ then docker_compose_file_available=0 fi -current_tag=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d ":" -f 2) +current_tag=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) if [ "$current_tag" == "" ] then @@ -389,7 +389,7 @@ tag_changed=0 IFS=' ' flag_list="${array_flag_list[*]}" if [[ -n "$tag" ]] then - current_tag=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d ":" -f 2) + current_tag=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) if [ "$current_tag" == "" ] then From 32bffeb32b0285a97a2124768660c844bcdf1d3d Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 25 Nov 2024 10:36:50 +0100 Subject: [PATCH 058/659] added mTLS example but not working due to hostname verification --- ccloud/fm-mqtt-source/docker-compose.mtls.yml | 37 ++++++ .../fully-managed-mqtt-source-mtls.sh | 108 ++++++++++++++++++ ccloud/fm-mqtt-source/mtls/mosquitto.conf | 10 ++ .../fm-mqtt-source/security/certs-create.sh | 80 +++++++++++++ 4 files changed, 235 insertions(+) create mode 100644 ccloud/fm-mqtt-source/docker-compose.mtls.yml create mode 100755 ccloud/fm-mqtt-source/fully-managed-mqtt-source-mtls.sh create mode 100644 ccloud/fm-mqtt-source/mtls/mosquitto.conf create mode 100755 ccloud/fm-mqtt-source/security/certs-create.sh diff --git a/ccloud/fm-mqtt-source/docker-compose.mtls.yml b/ccloud/fm-mqtt-source/docker-compose.mtls.yml new file mode 100644 index 0000000000..3721f44994 --- /dev/null +++ b/ccloud/fm-mqtt-source/docker-compose.mtls.yml @@ -0,0 +1,37 @@ +--- +services: + + mosquitto: + image: eclipse-mosquitto:1.6.13 + hostname: mosquitto + container_name: mosquitto + ports: + - 9001:9001 + - 1883:1883 + volumes: + - ../../ccloud/fm-mqtt-source/mtls/mosquitto.conf:/mosquitto/config/mosquitto.conf + - ../../ccloud/fm-mqtt-source/password:/etc/mosquitto/passwd + - ../../ccloud/fm-mqtt-source/security/snakeoil-ca-1.crt:/tmp/ca.crt + - ../../ccloud/fm-mqtt-source/security/mosquitto.certificate.pem:/tmp/server.crt + - ../../ccloud/fm-mqtt-source/security/mosquitto.key:/tmp/server.key + + # https://ngrok.com/docs/using-ngrok-with/docker/ + ngrok: + image: ngrok/ngrok:latest + hostname: ngrok + container_name: ngrok + ports: + - 4040:4040 + restart: unless-stopped + links: + - mosquitto + command: + - "start" + - "--all" + - "--log=stdout" + - "--config" + - "/etc/ngrok.yml" + volumes: + - ../../ccloud/fm-mqtt-source/ngrok.yml:/etc/ngrok.yml + environment: + NGROK_AUTHTOKEN: $NGROK_AUTH_TOKEN \ No newline at end of file diff --git a/ccloud/fm-mqtt-source/fully-managed-mqtt-source-mtls.sh b/ccloud/fm-mqtt-source/fully-managed-mqtt-source-mtls.sh new file mode 100755 index 0000000000..ca8a15ee4b --- /dev/null +++ b/ccloud/fm-mqtt-source/fully-managed-mqtt-source-mtls.sh @@ -0,0 +1,108 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +cd ${DIR}/security +log "🔐 Generate keys and certificates used for SSL" +docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/ && chmod a+r /tmp/*" +base64_truststore=$(cat $PWD/kafka.connect.truststore.jks | base64 | tr -d '\n') +base64_keystore=$(cat $PWD/kafka.connect.keystore.jks | base64 | tr -d '\n') +cd ${DIR} + +NGROK_AUTH_TOKEN=${NGROK_AUTH_TOKEN:-$1} + +display_ngrok_warning + +bootstrap_ccloud_environment + + + +set +e +playground topic delete --topic mqtt-source-1 +set -e + +docker compose -f docker-compose.mtls.yml build +docker compose -f docker-compose.mtls.yml down -v --remove-orphans +docker compose -f docker-compose.mtls.yml up -d --quiet-pull + +sleep 5 + +log "Waiting for ngrok to start" +while true +do + container_id=$(docker ps -q -f name=ngrok) + if [ -n "$container_id" ] + then + status=$(docker inspect --format '{{.State.Status}}' $container_id) + if [ "$status" = "running" ] + then + log "Getting ngrok hostname and port" + NGROK_URL=$(curl --silent http://127.0.0.1:4040/api/tunnels | jq -r '.tunnels[0].public_url') + NGROK_HOSTNAME=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 1) + NGROK_PORT=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 2) + + if ! [[ $NGROK_PORT =~ ^[0-9]+$ ]] + then + log "NGROK_PORT is not a valid number, keep retrying..." + continue + else + break + fi + fi + fi + log "Waiting for container ngrok to start..." + sleep 5 +done + +connector_name="MqttSourceMTLS_$USER" +set +e +playground connector delete --connector $connector_name > /dev/null 2>&1 +set -e + +log "Creating fully managed connector" +playground connector create-or-update --connector $connector_name << EOF +{ + "connector.class": "MqttSource", + "name": "$connector_name", + "kafka.auth.mode": "KAFKA_API_KEY", + "kafka.api.key": "$CLOUD_KEY", + "kafka.api.secret": "$CLOUD_SECRET", + "output.data.format": "AVRO", + "kafka.topic": "mqtt-source-1", + "mqtt.qos": "2", + "mqtt.server.uri" : "ssl://$NGROK_HOSTNAME:$NGROK_PORT", + "mqtt.topics":"my-mqtt-topic", + "mqtt.username": "myuser", + "mqtt.password": "mypassword", + + "mqtt.ssl.trust.store.file": "data:text/plain;base64,$base64_truststore", + "mqtt.ssl.trust.store.password": "confluent", + "mqtt.ssl.key.store.file": "data:text/plain;base64,$base64_keystore", + "mqtt.ssl.key.store.password": "confluent", + "mqtt.ssl.key.password": "confluent", + "tasks.max" : "1" +} +EOF +wait_for_ccloud_connector_up $connector_name 180 + + +# MqttSourceMTLS_vsaboulin ❌ FAILED 🤔 N/A connector: Unable to validate configuration. If an update was made to the configuration, this means that the configuration was invalid, and the connector continues to operate on a previous configuration that passed validation. Errors: +# mqtt.server.uri: MqttException (0) - javax.net.ssl.SSLHandshakeException: No subject alternative DNS name matching 4.tcp.eu.ngrok.io found. validation_errors: mqtt.server.uri: MqttException (0) - javax.net.ssl.SSLHandshakeException: No subject alternative DNS name matching 4.tcp.eu.ngrok.io found. + + +sleep 5 + +log "Send message to MQTT in my-mqtt-topic topic" +docker exec mosquitto sh -c 'mosquitto_pub -h localhost -p 8883 -u "myuser" -P "mypassword" -t "my-mqtt-topic" -m "sample-msg-1" --cafile /tmp/ca.crt --key /tmp/server.key --cert /tmp/server.crt' + +sleep 5 + +log "Verify we have received the data in mqtt-source-1 topic" +playground topic consume --topic mqtt-source-1 --min-expected-messages 1 --timeout 60 + +log "Do you want to delete the fully managed connector $connector_name ?" +check_if_continue + +playground connector delete --connector $connector_name \ No newline at end of file diff --git a/ccloud/fm-mqtt-source/mtls/mosquitto.conf b/ccloud/fm-mqtt-source/mtls/mosquitto.conf new file mode 100644 index 0000000000..720c1bb6a7 --- /dev/null +++ b/ccloud/fm-mqtt-source/mtls/mosquitto.conf @@ -0,0 +1,10 @@ +listener 1883 +persistence false +log_dest stdout +allow_anonymous false +connection_messages true +cafile /tmp/ca.crt +keyfile /tmp/server.key +certfile /tmp/server.crt +require_certificate true +tls_version tlsv1.2 diff --git a/ccloud/fm-mqtt-source/security/certs-create.sh b/ccloud/fm-mqtt-source/security/certs-create.sh new file mode 100755 index 0000000000..d047f00729 --- /dev/null +++ b/ccloud/fm-mqtt-source/security/certs-create.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +#set -o nounset \ +# -o errexit \ +# -o verbose \ +# -o xtrace + +# Cleanup files +rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile + +# Generate CA key +openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent + +for i in connect mosquitto +do + echo "------------------------------- $i -------------------------------" + + # Create host keystore + keytool -genkey -noprompt \ + -alias $i \ + -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ + -ext "SAN=dns:$i,dns:localhost" \ + -keystore /tmp/kafka.$i.keystore.jks \ + -keyalg RSA \ + -storepass confluent \ + -keypass confluent \ + -storetype pkcs12 + + # Create the certificate signing request (CSR) + keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" + #openssl req -in $i.csr -text -noout + +cat << EOF > /tmp/extfile +[req] +distinguished_name = req_distinguished_name +x509_extensions = v3_req +prompt = no +[req_distinguished_name] +CN = $i +[v3_req] +subjectAltName = @alt_names +[alt_names] +DNS.1 = $i +DNS.2 = localhost +EOF + # Sign the host certificate with the certificate authority (CA) + openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile + + #openssl x509 -noout -text -in $i-ca1-signed.crt + + # Sign and import the CA cert into the keystore + keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent + #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent + + # Sign and import the host certificate into the keystore + keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" + #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent + + # Create truststore and import the CA cert + keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent + + # Save creds + echo "confluent" > ${i}_sslkey_creds + echo "confluent" > ${i}_keystore_creds + echo "confluent" > ${i}_truststore_creds + + # Create pem files and keys used for Schema Registry HTTPS testing + # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 + # openssl rsa -noout -modulus -in client.key | openssl md5 + # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 + keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent + openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem + keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt + openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent + + + cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" + keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent + +done From 0754ee6ee676e34c56c023b7c6f0c16a63ede649 Mon Sep 17 00:00:00 2001 From: Catalin Pop Date: Mon, 25 Nov 2024 15:35:03 -0500 Subject: [PATCH 059/659] working on adding grafana dashboards for flink --- flink/flink_session_mode/docker-compose.yml | 75 ++++++++++++++++++++- flink/flink_session_mode/start.sh | 2 +- flink/flink_session_mode/stop.sh | 4 +- 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/flink/flink_session_mode/docker-compose.yml b/flink/flink_session_mode/docker-compose.yml index 5075dcb66e..7be94653d6 100644 --- a/flink/flink_session_mode/docker-compose.yml +++ b/flink/flink_session_mode/docker-compose.yml @@ -21,4 +21,77 @@ services: - | FLINK_PROPERTIES= jobmanager.rpc.address: jobmanager - taskmanager.numberOfTaskSlots: 2 \ No newline at end of file + taskmanager.numberOfTaskSlots: 2 + ${GRAFANA_FLINK} + + prometheus: + image: prom/prometheus:v2.29.2 + hostname: prometheus + container_name: prometheus + profiles: + - "grafana" + ports: + - 9090:9090 + volumes: + - ../../environment/plaintext/prometheus/:/etc/prometheus/ + + depends_on: + - node-exporter + - kafka-lag-exporter + - alertmanager + + grafana: + image: grafana/grafana:8.5.27 + hostname: grafana + container_name: grafana + profiles: + - "grafana" + environment: + - "GF_SECURITY_ADMIN_USER=admin" + - "GF_SECURITY_ADMIN_PASSWORD=password" + - "GF_USERS_ALLOW_SIGN_UP=false" + ports: + - 3000:3000 + volumes: + - ../../environment/plaintext/grafana/provisioning/:/etc/grafana/provisioning/ + - ../../environment/plaintext/grafana/config/grafana.ini:/etc/grafana/grafana.ini + depends_on: + - prometheus + + node-exporter: + image: prom/node-exporter:v1.2.2 + hostname: node-exporter + container_name: node-exporter + profiles: + - "grafana" + volumes: + - /proc:/host/proc:ro + - /sys:/host/sys:ro + - /:/rootfs:ro + command: + - "--path.procfs=/host/proc" + - "--path.sysfs=/host/sys" + - "--collector.filesystem.ignored-mount-points" + - "^(aufs|proc|nsfs|shm|cgroup|tmpfs|binfmt_misc|debugfs|devpts|fusectl|hugetlbfs|fuse.lxcfs|mqueue|pstore|securityfs|sysfs|autofs|devtmpfs|configfs)" + + kafka-lag-exporter: + image: seglo/kafka-lag-exporter:0.7.1 + hostname: kafka-lag-exporter + container_name: kafka-lag-exporter + profiles: + - "grafana" + restart: always + ports: + - 9998:9998 + volumes: + - ../../environment/plaintext/kafka-lag-exporter/application.conf:/opt/docker/conf/application.conf + - ../../environment/plaintext/kafka-lag-exporter/logback.xml:/opt/docker/conf/logback.xml + + alertmanager: + image: prom/alertmanager:latest + hostname: alertmanager + container_name: alertmanager + profiles: + - "grafana" + ports: + - 9093:9093 \ No newline at end of file diff --git a/flink/flink_session_mode/start.sh b/flink/flink_session_mode/start.sh index 3f6a696f54..c7595e73d6 100755 --- a/flink/flink_session_mode/start.sh +++ b/flink/flink_session_mode/start.sh @@ -7,4 +7,4 @@ source ${DIR}/../../scripts/utils.sh source ${DIR}/../../scripts/flink_download_connectors.sh -docker-compose up -d \ No newline at end of file +docker compose --profile grafana up -d \ No newline at end of file diff --git a/flink/flink_session_mode/stop.sh b/flink/flink_session_mode/stop.sh index 7962d46338..d3f22b0d9e 100755 --- a/flink/flink_session_mode/stop.sh +++ b/flink/flink_session_mode/stop.sh @@ -1,9 +1,9 @@ #!/bin/bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -echo "Pops ${DIR}" + source ${DIR}/../../scripts/utils.sh -docker-compose down -v --remove-orphans +docker-compose --profile grafana down -v --remove-orphans stop_all "$DIR" \ No newline at end of file From d226b77883c7b2d22e9c6cac8cdd04cc84e9d98b Mon Sep 17 00:00:00 2001 From: Catalin Pop Date: Mon, 25 Nov 2024 19:32:47 -0500 Subject: [PATCH 060/659] grafana dashboard and env variables should work in all deployment modes --- flink/flink_session_mode/start.sh | 12 ++++++++++-- flink/flink_session_mode/stop.sh | 12 +++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/flink/flink_session_mode/start.sh b/flink/flink_session_mode/start.sh index c7595e73d6..f3e104a4d8 100755 --- a/flink/flink_session_mode/start.sh +++ b/flink/flink_session_mode/start.sh @@ -4,7 +4,15 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" # loading env variables source ${DIR}/../../scripts/utils.sh +profile_grafana_command="" + if [ -z "$ENABLE_JMX_GRAFANA" ] + then + log "🛑 Grafana is disabled" + else + log "📊 Grafana is enabled" + profile_grafana_command="--profile grafana" + playground state set flags.ENABLE_JMX_GRAFANA 1 + fi source ${DIR}/../../scripts/flink_download_connectors.sh - -docker compose --profile grafana up -d \ No newline at end of file +docker compose ${profile_grafana_command} up -d \ No newline at end of file diff --git a/flink/flink_session_mode/stop.sh b/flink/flink_session_mode/stop.sh index d3f22b0d9e..a86c77b675 100755 --- a/flink/flink_session_mode/stop.sh +++ b/flink/flink_session_mode/stop.sh @@ -4,6 +4,16 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -docker-compose --profile grafana down -v --remove-orphans +profile_grafana_command="" +if [ -z "$ENABLE_JMX_GRAFANA" ] +then + log "🛑 Grafana is disabled" +else + log "📊 Grafana is enabled" + profile_grafana_command="--profile grafana" + playground state set flags.ENABLE_JMX_GRAFANA 1 +fi + +docker-compose ${profile_grafana_command} down -v --remove-orphans stop_all "$DIR" \ No newline at end of file From 7aedf2d5e04891bbf349dddd5c96cbcbe3be37b0 Mon Sep 17 00:00:00 2001 From: Catalin Pop Date: Mon, 25 Nov 2024 19:37:47 -0500 Subject: [PATCH 061/659] grafana dashboard and env variables should work in all deployment modes --- environment/plaintext/docker-compose.yml | 8 +- .../provisioning/dashboards/flink.json | 7603 +++++++++++++++++ .../plaintext/prometheus/prometheus.yml | 8 + flink/flink_app_mode/docker-compose.yml | 78 +- flink/flink_app_mode/start.sh | 12 +- flink/flink_app_mode/stop.sh | 12 +- .../flink_session_sql_mode/docker-compose.yml | 77 +- flink/flink_session_sql_mode/start.sh | 12 +- flink/flink_session_sql_mode/stop.sh | 12 +- scripts/flink_download_connectors.sh | 242 +- scripts/utils.sh | 3 + 11 files changed, 7937 insertions(+), 130 deletions(-) create mode 100644 environment/plaintext/grafana/provisioning/dashboards/flink.json diff --git a/environment/plaintext/docker-compose.yml b/environment/plaintext/docker-compose.yml index 65f11168e8..a0d460181b 100644 --- a/environment/plaintext/docker-compose.yml +++ b/environment/plaintext/docker-compose.yml @@ -615,7 +615,8 @@ services: profiles: - flink ports: - - "18081:18081" # Expose port 18081 for REST API and Web UI + - "18081:18081" # REST API and Web UI + - "9090:9090" # Prometheus metrics entrypoint: > sh -c "$flink_connectors exec /docker-entrypoint.sh jobmanager" environment: @@ -624,7 +625,8 @@ services: jobmanager.rpc.address: jobmanager rest.port: 18081 taskmanager.numberOfTaskSlots: 4 - + ${GRAFANA_FLINK} + # Flink TaskManager taskmanager: image: flink:${FLINK_TAG} @@ -643,7 +645,7 @@ services: rest.address: jobmanager rest.port: 18081 taskmanager.numberOfTaskSlots: 4 - + ${GRAFANA_FLINK} # Flink SQL Client sql-client: image: flink:${FLINK_TAG} diff --git a/environment/plaintext/grafana/provisioning/dashboards/flink.json b/environment/plaintext/grafana/provisioning/dashboards/flink.json new file mode 100644 index 0000000000..52da5127e1 --- /dev/null +++ b/environment/plaintext/grafana/provisioning/dashboards/flink.json @@ -0,0 +1,7603 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "description": "", + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "iteration": 1629750069653, + "links": [], + "panels": [ + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 113, + "panels": [ + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 0, + "y": 1 + }, + "id": 114, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_Status_JVM_CPU_Load{instance=~\"$jm_instance\"}", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "title": "Load", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ns" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 8, + "y": 1 + }, + "id": 115, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_jobmanager_Status_JVM_CPU_Time{instance=~\"$jm_instance\"}[1m])", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "title": "Time", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 1 + }, + "id": 116, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_Status_JVM_Threads_Count{instance=~\"$jm_instance\"}", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "title": "Threads", + "type": "timeseries" + } + ], + "title": "Job Manager (JVM - CPU)", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 122, + "panels": [ + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 2 + }, + "id": 123, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_Status_JVM_Memory_Heap_Used{instance=~\"$jm_instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "title": "Heap", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 2 + }, + "id": 124, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_Status_JVM_Memory_NonHeap_Used{instance=~\"$jm_instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "title": "Heap", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 8, + "x": 0, + "y": 10 + }, + "id": 125, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_Status_JVM_Memory_Direct_MemoryUsed{instance=~\"$jm_instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "title": "Direct", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 8, + "x": 8, + "y": 10 + }, + "id": 126, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_Status_JVM_Memory_Mapped_MemoryUsed{instance=~\"$jm_instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "title": "Mapped", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 8, + "x": 16, + "y": 10 + }, + "id": 127, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_Status_JVM_Memory_Metaspace_Used{instance=~\"$jm_instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "title": "Metaspace", + "type": "timeseries" + } + ], + "title": "Job Manager (JVM - Memory Usage)", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 2 + }, + "id": 118, + "panels": [ + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 3 + }, + "id": 119, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_Status_JVM_GarbageCollector_PS_MarkSweep_Time", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "title": "Mark Sweep Time", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 3 + }, + "id": 120, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_jobmanager_Status_JVM_GarbageCollector_PS_Scavenge_Time[1m])", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "title": "Scavenge Time", + "type": "timeseries" + } + ], + "title": "Job Manager (JVM - Garbage Collector)", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 3 + }, + "id": 10, + "panels": [ + { + "cacheTimeout": null, + "datasource": "${Source}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 3, + "x": 0, + "y": 4 + }, + "id": 2, + "interval": null, + "links": [], + "maxDataPoints": null, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_numRegisteredTaskManagers{instance=~\"$jm_instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Task Managers", + "type": "timeseries" + }, + { + "cacheTimeout": null, + "datasource": "${Source}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 7, + "x": 3, + "y": 4 + }, + "id": 31, + "interval": null, + "links": [], + "maxDataPoints": null, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_taskSlotsTotal{instance=~\"$jm_instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Task Slots", + "type": "timeseries" + }, + { + "cacheTimeout": null, + "datasource": "${Source}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 7, + "x": 10, + "y": 4 + }, + "id": 32, + "interval": null, + "links": [], + "maxDataPoints": null, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_taskSlotsAvailable{instance=~\"$jm_instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Available Task Slots", + "type": "timeseries" + }, + { + "cacheTimeout": null, + "datasource": "${Source}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 7, + "x": 17, + "y": 4 + }, + "id": 33, + "interval": null, + "links": [], + "maxDataPoints": null, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_numRunningJobs{instance=~\"$jm_instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Runnings Jobs", + "type": "timeseries" + }, + { + "cacheTimeout": null, + "datasource": "${Source}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 12 + }, + "id": 34, + "interval": null, + "links": [], + "maxDataPoints": null, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_job_numRestarts{job_name=~\"$job_name\", instance=~\"$jm_instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{job_name}} ({{job_id}}) on {{instance}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Job Restarts", + "transformations": [], + "type": "timeseries" + }, + { + "cacheTimeout": null, + "datasource": "${Source}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 12 + }, + "id": 42, + "interval": null, + "links": [], + "maxDataPoints": null, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_job_fullRestarts{job_name=~\"$job_name\", instance=~\"$jm_instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{job_name}} ({{job_id}}) on {{instance}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Job Restarts", + "type": "timeseries" + }, + { + "cacheTimeout": null, + "datasource": "${Source}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 12 + }, + "id": 43, + "interval": null, + "links": [], + "maxDataPoints": null, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_job_restartingTime{job_name=~\"$job_name\", instance=~\"$jm_instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{job_name}} ({{job_id}}) on {{instance}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Job Restartine Time", + "type": "timeseries" + }, + { + "cacheTimeout": null, + "datasource": "${Source}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + }, + { + "color": "dark-yellow", + "value": 3600000 + }, + { + "color": "dark-orange", + "value": 21600000 + }, + { + "color": "dark-purple", + "value": 86400000 + }, + { + "color": "dark-red", + "value": 259200000 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 21, + "x": 0, + "y": 20 + }, + "id": 37, + "interval": null, + "links": [], + "maxDataPoints": null, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_job_uptime{job_name=~\"$job_name\", instance=~\"$jm_instance\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{job_id}} ({{instance}})", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Job Uptime", + "type": "stat" + }, + { + "datasource": null, + "description": "", + "gridPos": { + "h": 10, + "w": 3, + "x": 21, + "y": 20 + }, + "id": 46, + "options": { + "content": "# Uptime Description\n\n| Color | Status|\n|---|---|\n| Green | < 1 Hour |\n| Yellow | >= 1 Hour |\n| Orange | >= 6 Hours |\n| Purple | >= 1 Day |\n| Red | >= 3 days |\n", + "mode": "markdown" + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "refId": "A", + "target": "" + } + ], + "title": "Uptime Derscription", + "type": "text" + } + ], + "title": "Job Manager (Slots & Jobs)", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 4 + }, + "id": 106, + "panels": [ + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 6, + "x": 0, + "y": 5 + }, + "id": 108, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_jobmanager_job_totalNumberOfCheckpoints{job_name=~\"$job_name\", instance=~\"$jm_instance\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}}) on {{instance}}", + "refId": "A" + } + ], + "title": "Checkpoints", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 6, + "x": 6, + "y": 5 + }, + "id": 109, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_jobmanager_job_numberOfCompletedCheckpoints{job_name=~\"$job_name\", instance=~\"$jm_instance\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}}) on {{instance}}", + "refId": "A" + } + ], + "title": "Completed Checkpoints", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 6, + "x": 12, + "y": 5 + }, + "id": 111, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_jobmanager_job_numberOfInProgressCheckpoints{job_name=~\"$job_name\", instance=~\"$jm_instance\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}}) on {{instance}}", + "refId": "A" + } + ], + "title": "In Progress Checkpoints", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 6, + "x": 18, + "y": 5 + }, + "id": 110, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_jobmanager_job_numberOfFailedCheckpoints{job_name=~\"$job_name\", instance=~\"$jm_instance\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}}) on {{instance}}", + "refId": "A" + } + ], + "title": "Failed Checkpoints", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 0, + "y": 16 + }, + "id": 129, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_job_lastCheckpointSize{job_name=~\"$job_name\", instance=~\"$jm_instance\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}}) on {{instance}}", + "refId": "A" + } + ], + "title": "Last Checkpoint Size", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 8, + "y": 16 + }, + "id": 130, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_jobmanager_job_lastCheckpointDuration{job_name=~\"$job_name\", instance=~\"$jm_instance\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}}) on {{instance}}", + "refId": "A" + } + ], + "title": "Last Checkpoint Duration", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 16 + }, + "id": 131, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "xx{job_name=~\"$job_name\", instance=~\"$jm_instance\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}}) on {{instance}}", + "refId": "A" + } + ], + "type": "timeseries" + } + ], + "title": "Job Manager (Checkpoints)", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 5 + }, + "id": 91, + "panels": [ + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 0, + "y": 6 + }, + "id": 93, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_JVM_CPU_Load{tm_id=~\"${tm_id}\"}", + "interval": "", + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Load", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ns" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 8, + "y": 6 + }, + "id": 94, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "increase(flink_taskmanager_Status_JVM_CPU_Time{tm_id=~\"$tm_id\"}[1m])", + "interval": "", + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Time", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 6 + }, + "id": 95, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_JVM_Threads_Count{tm_id=~\"${tm_id}\"}", + "interval": "", + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Threads", + "type": "timeseries" + } + ], + "title": "Task Manager (JVM - CPU)", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 6 + }, + "id": 16, + "panels": [ + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 7 + }, + "id": 27, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_JVM_Memory_Heap_Used{tm_id=~\"$tm_id\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Heap", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 7 + }, + "id": 28, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_JVM_Memory_NonHeap_Used{tm_id=~\"$tm_id\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Non Heap", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 8, + "x": 0, + "y": 16 + }, + "id": 29, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_JVM_Memory_Direct_MemoryUsed{tm_id=~\"$tm_id\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Direct", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 8, + "x": 8, + "y": 16 + }, + "id": 89, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_JVM_Memory_Mapped_MemoryUsed{tm_id=~\"$tm_id\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Mapped", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 8, + "x": 16, + "y": 16 + }, + "id": 20, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_JVM_Memory_Metaspace_Used{tm_id=~\"$tm_id\"}", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Metaspace", + "type": "timeseries" + } + ], + "title": "Task Manager (JVM - Memory Usage)", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 7 + }, + "id": 48, + "panels": [ + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 44, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_JVM_GarbageCollector_G1_Young_Generation_Time{tm_id=~\"$tm_id\"}", + "interval": "", + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Young Generation Time", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 41, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_JVM_GarbageCollector_G1_Old_Generation_Time{tm_id=~\"$tm_id\"}", + "interval": "", + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Old Generation Time", + "type": "timeseries" + } + ], + "title": "Task Manager (JVM - Garbage Collector)", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 135, + "panels": [ + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 137, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_Flink_Memory_Managed_Used{tm_id=~\"$tm_id\"}", + "interval": "", + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Managed", + "type": "timeseries" + } + ], + "title": "Task Manager (Memory - Flink)", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 55, + "panels": [ + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 10 + }, + "id": 132, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_Shuffle_Netty_TotalMemory{tm_id=~\"$tm_id\"}", + "interval": "", + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Total Memory", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 10 + }, + "id": 133, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_Shuffle_Netty_TotalMemorySegments{tm_id=~\"$tm_id\"}", + "interval": "", + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Total Memory Segments", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 6, + "x": 0, + "y": 20 + }, + "id": 57, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_Shuffle_Netty_UsedMemory{tm_id=~\"$tm_id\"}", + "interval": "", + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Used Memory", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 6, + "x": 6, + "y": 20 + }, + "id": 76, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_Shuffle_Netty_AvailableMemory{tm_id=~\"$tm_id\"}", + "interval": "", + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Available Memory", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 6, + "x": 12, + "y": 20 + }, + "id": 77, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_Shuffle_Netty_UsedMemorySegments{tm_id=~\"$tm_id\"}", + "interval": "", + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Used Memory Segments", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 6, + "x": 18, + "y": 20 + }, + "id": 78, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_Status_Shuffle_Netty_AvailableMemorySegments{tm_id=~\"$tm_id\"}", + "interval": "", + "legendFormat": "{{tm_id}}", + "refId": "A" + } + ], + "title": "Available Memory Segments", + "type": "timeseries" + } + ], + "title": "Task Manager (Memory - Shuffle Netty)", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 53, + "panels": [ + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 6, + "x": 0, + "y": 11 + }, + "id": 50, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_isBackPressured{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Is Back Pressured", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 6, + "x": 6, + "y": 11 + }, + "id": 51, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_idleTimeMsPerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Idle Time Ms (per Second)", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ns" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 6, + "x": 12, + "y": 11 + }, + "id": 80, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_checkpointStartDelayNanos{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Checkpoint Alignment Time", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 6, + "x": 18, + "y": 11 + }, + "id": 79, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_checkpointAlignmentTime{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Checkpoint Alignment Time", + "type": "timeseries" + } + ], + "title": "Task Manager (Job Task - Diag)", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 11 + }, + "id": 139, + "panels": [ + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 0, + "y": 12 + }, + "id": 141, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_numBuffersInLocal{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Number Buffers in Local", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "cps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 6, + "y": 12 + }, + "id": 142, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_numBuffersInLocalPerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Number Buffers in Local (per Second)", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 12, + "y": 12 + }, + "id": 143, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_numBuffersInRemote{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Number Buffers in Remote", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "cps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 18, + "y": 12 + }, + "id": 144, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_numBuffersInRemotePerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Number Buffers in Remote (per Second)", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 21 + }, + "id": 145, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_taskmanager_job_task_numBuffersOut{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Number Buffers Out", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "cps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 21 + }, + "id": 146, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_numBuffersOutPerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Number Buffers Out (per Second)", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 4, + "x": 0, + "y": 29 + }, + "id": 147, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_taskmanager_job_task_numBytesIn{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Bytes In", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "binBps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 4, + "x": 4, + "y": 29 + }, + "id": 148, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_numBytesInPerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Bytes In (per Second)", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 4, + "x": 8, + "y": 29 + }, + "id": 149, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_taskmanager_job_task_numBytesInLocal{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Bytes In Local", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "binBps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 4, + "x": 12, + "y": 29 + }, + "id": 150, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_numBytesInLocalPerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Bytes In Local (per Second)", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 4, + "x": 16, + "y": 29 + }, + "id": 151, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_taskmanager_job_task_numBytesInRemote{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Bytes In Remote", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "binBps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 4, + "x": 20, + "y": 29 + }, + "id": 152, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_numBytesInRemotePerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Bytes In Remote (per Second)", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 38 + }, + "id": 153, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_taskmanager_job_task_numBytesOut{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Bytes Out", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "binBps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 38 + }, + "id": 154, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_numBytesOutPerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Bytes Out (per Second)", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "cps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 0, + "y": 47 + }, + "id": 155, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_taskmanager_job_task_numRecordsIn{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Records In", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "cps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 6, + "y": 47 + }, + "id": 156, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_numRecordsInPerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Bytes In (per Second)", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "cps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 12, + "y": 47 + }, + "id": 157, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_taskmanager_job_task_numRecordsOut{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Records Out", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "cps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 18, + "y": 47 + }, + "id": 158, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_numRecordsOutPerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Bytes Out (per Second)", + "type": "timeseries" + } + ], + "title": "Task Manager (Job Task - General)", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 12 + }, + "id": 97, + "panels": [ + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 0, + "y": 13 + }, + "id": 99, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_buffers_inPoolUsage{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "In Pool Usage", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 8, + "y": 13 + }, + "id": 103, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_buffers_inputQueueLength{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Input Queue Length", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 13 + }, + "id": 100, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_buffers_inputExclusiveBuffersUsage{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Input Exclusive Buffers Usage", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 0, + "y": 23 + }, + "id": 102, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_buffers_outPoolUsage{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Out Pool Usage", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 8, + "y": 23 + }, + "id": 104, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_buffers_outputQueueLength{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Output Queue Length", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 23 + }, + "id": 101, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_buffers_inputFloatingBuffersUsage{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Input Floating Buffers Usage", + "type": "timeseries" + } + ], + "title": "Task Manager (Job Task - Buffers)", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 13 + }, + "id": 82, + "panels": [ + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 4, + "x": 0, + "y": 14 + }, + "id": 84, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_operator_numLateRecordsDropped", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Number Late Records Dropped", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 5, + "x": 4, + "y": 14 + }, + "id": 85, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_taskmanager_job_task_operator_numRecordsIn{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Number Records In", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "cps" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 5, + "x": 9, + "y": 14 + }, + "id": 87, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_operator_numRecordsInPerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Number Records Out (per Second)", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 5, + "x": 14, + "y": 14 + }, + "id": 86, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_taskmanager_job_task_operator_numRecordsOut{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Number Records In", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 5, + "x": 19, + "y": 14 + }, + "id": 88, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_operator_numRecordsOutPerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Num Records Out (per Second)", + "type": "timeseries" + } + ], + "title": "Task Manager (Job Task - Operator)", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 60, + "panels": [ + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 15 + }, + "id": 58, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_Shuffle_Netty_Input_Buffers_inputQueueLength{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Input Queue Length", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 15 + }, + "id": 62, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_Shuffle_Netty_Output_Buffers_outputQueueLength{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Output Queue Length", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 0, + "y": 24 + }, + "id": 63, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_Shuffle_Netty_Input_Buffers_inPoolUsage{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "In Pool Usage", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 6, + "y": 24 + }, + "id": 67, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_Shuffle_Netty_Output_Buffers_outPoolUsage{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Out Pool Usage", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 12, + "y": 24 + }, + "id": 65, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_Shuffle_Netty_Input_Buffers_inputFloatingBuffersUsage{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Input Floating Buffers Usage", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 18, + "y": 24 + }, + "id": 66, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_Shuffle_Netty_Input_Buffers_inputExclusiveBuffersUsage{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Input Exclusive Buffers Usage", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 0, + "y": 33 + }, + "id": 68, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_Shuffle_Netty_Input_numBuffersInLocal{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Input Number Buffers In Local", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "cps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 6, + "y": 33 + }, + "id": 72, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_Shuffle_Netty_Input_numBuffersInLocalPerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Input Number Buffers In Local (per Second)", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 12, + "y": 33 + }, + "id": 70, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "flink_taskmanager_job_task_Shuffle_Netty_Input_numBuffersInRemote{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Input Number Buffers In Remote", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 18, + "y": 33 + }, + "id": 71, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_Shuffle_Netty_Input_numBuffersInRemotePerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Input Num Buffers In Remote (per Second)", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 0, + "y": 42 + }, + "id": 69, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_taskmanager_job_task_Shuffle_Netty_Input_numBytesInLocal{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Input Num Bytes In Local", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "binBps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 6, + "y": 42 + }, + "id": 73, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_Shuffle_Netty_Input_numBytesInLocalPerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Input Number Bytes In Local (per Second)", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 12, + "y": 42 + }, + "id": 74, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "delta(flink_taskmanager_job_task_Shuffle_Netty_Input_numBytesInRemote{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Input Number Bytes In Remote", + "type": "timeseries" + }, + { + "datasource": "${Source}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "binBps" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 18, + "y": 42 + }, + "id": 75, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "rate(flink_taskmanager_job_task_Shuffle_Netty_Input_numBytesInRemotePerSecond{tm_id=~\"$tm_id\", job_name=~\"$job_name\", task_name=~\"$task_name\"}[1m])", + "interval": "", + "legendFormat": "{{job_name}} ({{job_id}} / {{task_id}}) {{tm_id}}", + "refId": "A" + } + ], + "title": "Input Number Bytes In Remote (per Second)", + "type": "timeseries" + } + ], + "title": "Task Manager (Job Task - Shuffle Netty)", + "type": "row" + } + ], + "refresh": false, + "schemaVersion": 30, + "style": "dark", + "tags": [ + "flink", + "task manager", + "job manager", + "apache" + ], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": [ + "prometheus" + ], + "value": [ + "prometheus" + ] + }, + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": true, + "name": "Source", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": null, + "current": { + "selected": true, + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": "Prometheus", + "definition": "label_values(tm_id)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": "Task Manager", + "multi": true, + "name": "tm_id", + "options": [], + "query": { + "query": "label_values(tm_id)", + "refId": "StandardVariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "allValue": null, + "current": { + "selected": true, + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": "${Source}", + "definition": "label_values(flink_jobmanager_numRegisteredTaskManagers,instance)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": "Job Manager", + "multi": true, + "name": "jm_instance", + "options": [], + "query": { + "query": "label_values(flink_jobmanager_numRegisteredTaskManagers,instance)", + "refId": "StandardVariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "allValue": null, + "current": { + "selected": true, + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": "Prometheus", + "definition": "label_values(flink_taskmanager_job_task_isBackPressured{tm_id=~\"$tm_id\"},job_name)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": "Job Name", + "multi": true, + "name": "job_name", + "options": [], + "query": { + "query": "label_values(flink_taskmanager_job_task_isBackPressured{tm_id=~\"$tm_id\"},job_name)", + "refId": "StandardVariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "allValue": null, + "current": { + "selected": true, + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": "${Source}", + "definition": "label_values(flink_taskmanager_job_task_isBackPressured{job_name=~\"$job_name\"},task_name)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": "Task Name", + "multi": true, + "name": "task_name", + "options": [], + "query": { + "query": "label_values(flink_taskmanager_job_task_isBackPressured{job_name=~\"$job_name\"},task_name)", + "refId": "StandardVariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "datasource": null, + "description": null, + "error": null, + "filters": [], + "hide": 0, + "label": "Ad Hoc", + "name": "ad_hoc", + "skipUrlSync": false, + "type": "adhoc" + } + ] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Flink", + "uid": "wKbnD5Gnk", + "version": 1 + } \ No newline at end of file diff --git a/environment/plaintext/prometheus/prometheus.yml b/environment/plaintext/prometheus/prometheus.yml index 464b9d04ef..f99379c9d9 100644 --- a/environment/plaintext/prometheus/prometheus.yml +++ b/environment/plaintext/prometheus/prometheus.yml @@ -25,6 +25,14 @@ scrape_configs: static_configs: - targets: ["localhost:9090"] + - job_name: 'flink-jobmanager' + static_configs: + - targets: ['jobmanager:9090'] + + - job_name: 'flink-taskmanager' + static_configs: + - targets: ['taskmanager:9090'] + - job_name: "node-exporter" static_configs: diff --git a/flink/flink_app_mode/docker-compose.yml b/flink/flink_app_mode/docker-compose.yml index 7e8c0160c6..193e685604 100644 --- a/flink/flink_app_mode/docker-compose.yml +++ b/flink/flink_app_mode/docker-compose.yml @@ -8,7 +8,9 @@ services: volumes: - ${FLINK_JAR_PATH}:/opt/flink/job.jar environment: - - FLINK_PROPERTIES= + - | + FLINK_PROPERTIES= + ${GRAFANA_FLINK} taskmanager: image: flink:${FLINK_TAG} @@ -24,4 +26,76 @@ services: FLINK_PROPERTIES= jobmanager.rpc.address: jobmanager taskmanager.numberOfTaskSlots: 2 - parallelism.default: 2 \ No newline at end of file + parallelism.default: 2 + ${GRAFANA_FLINK} + + prometheus: + image: prom/prometheus:v2.29.2 + hostname: prometheus + container_name: prometheus + profiles: + - "grafana" + ports: + - 9090:9090 + volumes: + - ../../environment/plaintext/prometheus/:/etc/prometheus/ + depends_on: + - node-exporter + - kafka-lag-exporter + - alertmanager + + grafana: + image: grafana/grafana:8.5.27 + hostname: grafana + container_name: grafana + profiles: + - "grafana" + environment: + - "GF_SECURITY_ADMIN_USER=admin" + - "GF_SECURITY_ADMIN_PASSWORD=password" + - "GF_USERS_ALLOW_SIGN_UP=false" + ports: + - 3000:3000 + volumes: + - ../../environment/plaintext/grafana/provisioning/:/etc/grafana/provisioning/ + - ../../environment/plaintext/grafana/config/grafana.ini:/etc/grafana/grafana.ini + depends_on: + - prometheus + + node-exporter: + image: prom/node-exporter:v1.2.2 + hostname: node-exporter + container_name: node-exporter + profiles: + - "grafana" + volumes: + - /proc:/host/proc:ro + - /sys:/host/sys:ro + - /:/rootfs:ro + command: + - "--path.procfs=/host/proc" + - "--path.sysfs=/host/sys" + - "--collector.filesystem.ignored-mount-points" + - "^(aufs|proc|nsfs|shm|cgroup|tmpfs|binfmt_misc|debugfs|devpts|fusectl|hugetlbfs|fuse.lxcfs|mqueue|pstore|securityfs|sysfs|autofs|devtmpfs|configfs)" + + kafka-lag-exporter: + image: seglo/kafka-lag-exporter:0.7.1 + hostname: kafka-lag-exporter + container_name: kafka-lag-exporter + profiles: + - "grafana" + restart: always + ports: + - 9998:9998 + volumes: + - ../../environment/plaintext/kafka-lag-exporter/application.conf:/opt/docker/conf/application.conf + - ../../environment/plaintext/kafka-lag-exporter/logback.xml:/opt/docker/conf/logback.xml + + alertmanager: + image: prom/alertmanager:latest + hostname: alertmanager + container_name: alertmanager + profiles: + - "grafana" + ports: + - 9093:9093 \ No newline at end of file diff --git a/flink/flink_app_mode/start.sh b/flink/flink_app_mode/start.sh index 1a894d8418..336ebc2c23 100755 --- a/flink/flink_app_mode/start.sh +++ b/flink/flink_app_mode/start.sh @@ -11,6 +11,16 @@ then exit fi +profile_grafana_command="" +if [ -z "$ENABLE_JMX_GRAFANA" ] +then + log "🛑 Grafana is disabled" +else + log "📊 Grafana is enabled" + profile_grafana_command="--profile grafana" + playground state set flags.ENABLE_JMX_GRAFANA 1 +fi + source ${DIR}/../../scripts/flink_download_connectors.sh -docker-compose up -d \ No newline at end of file +docker compose ${profile_grafana_command} up -d \ No newline at end of file diff --git a/flink/flink_app_mode/stop.sh b/flink/flink_app_mode/stop.sh index eb1a7c66c6..b27c220ba6 100755 --- a/flink/flink_app_mode/stop.sh +++ b/flink/flink_app_mode/stop.sh @@ -3,5 +3,15 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -docker-compose down -v --remove-orphans +profile_grafana_command="" +if [ -z "$ENABLE_JMX_GRAFANA" ] +then + log "🛑 Grafana is disabled" +else + log "📊 Grafana is enabled" + profile_grafana_command="--profile grafana" + playground state set flags.ENABLE_JMX_GRAFANA 1 +fi + +docker-compose ${profile_grafana_command} down -v --remove-orphans stop_all "$DIR" diff --git a/flink/flink_session_sql_mode/docker-compose.yml b/flink/flink_session_sql_mode/docker-compose.yml index 8cfda4dfda..f2f6d8fee8 100644 --- a/flink/flink_session_sql_mode/docker-compose.yml +++ b/flink/flink_session_sql_mode/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.8' - services: # Flink JobManager jobmanager: @@ -14,6 +12,7 @@ services: - | FLINK_PROPERTIES= jobmanager.rpc.address: jobmanager + ${GRAFANA_FLINK} # Flink TaskManager taskmanager: @@ -30,6 +29,7 @@ services: jobmanager.rpc.address: jobmanager rest.address: jobmanager taskmanager.numberOfTaskSlots: 4 + ${GRAFANA_FLINK} # Flink SQL Client sql-client: @@ -48,4 +48,75 @@ services: FLINK_PROPERTIES= jobmanager.rpc.address: jobmanager rest.address: jobmanager - deployment.gateway-address: jobmanager \ No newline at end of file + deployment.gateway-address: jobmanager + + prometheus: + image: prom/prometheus:v2.29.2 + hostname: prometheus + container_name: prometheus + profiles: + - "grafana" + ports: + - 9090:9090 + volumes: + - ../../environment/plaintext/prometheus/:/etc/prometheus/ + depends_on: + - node-exporter + - kafka-lag-exporter + - alertmanager + + grafana: + image: grafana/grafana:8.5.27 + hostname: grafana + container_name: grafana + profiles: + - "grafana" + environment: + - "GF_SECURITY_ADMIN_USER=admin" + - "GF_SECURITY_ADMIN_PASSWORD=password" + - "GF_USERS_ALLOW_SIGN_UP=false" + ports: + - 3000:3000 + volumes: + - ../../environment/plaintext/grafana/provisioning/:/etc/grafana/provisioning/ + - ../../environment/plaintext/grafana/config/grafana.ini:/etc/grafana/grafana.ini + depends_on: + - prometheus + + node-exporter: + image: prom/node-exporter:v1.2.2 + hostname: node-exporter + container_name: node-exporter + profiles: + - "grafana" + volumes: + - /proc:/host/proc:ro + - /sys:/host/sys:ro + - /:/rootfs:ro + command: + - "--path.procfs=/host/proc" + - "--path.sysfs=/host/sys" + - "--collector.filesystem.ignored-mount-points" + - "^(aufs|proc|nsfs|shm|cgroup|tmpfs|binfmt_misc|debugfs|devpts|fusectl|hugetlbfs|fuse.lxcfs|mqueue|pstore|securityfs|sysfs|autofs|devtmpfs|configfs)" + + kafka-lag-exporter: + image: seglo/kafka-lag-exporter:0.7.1 + hostname: kafka-lag-exporter + container_name: kafka-lag-exporter + profiles: + - "grafana" + restart: always + ports: + - 9998:9998 + volumes: + - ../../environment/plaintext/kafka-lag-exporter/application.conf:/opt/docker/conf/application.conf + - ../../environment/plaintext/kafka-lag-exporter/logback.xml:/opt/docker/conf/logback.xml + + alertmanager: + image: prom/alertmanager:latest + hostname: alertmanager + container_name: alertmanager + profiles: + - "grafana" + ports: + - 9093:9093 \ No newline at end of file diff --git a/flink/flink_session_sql_mode/start.sh b/flink/flink_session_sql_mode/start.sh index 8d514a7339..1f5843f0f1 100755 --- a/flink/flink_session_sql_mode/start.sh +++ b/flink/flink_session_sql_mode/start.sh @@ -6,4 +6,14 @@ source ${DIR}/../../scripts/utils.sh source ${DIR}/../../scripts/flink_download_connectors.sh -docker-compose up -d \ No newline at end of file +profile_grafana_command="" +if [ -z "$ENABLE_JMX_GRAFANA" ] +then + log "🛑 Grafana is disabled" +else + log "📊 Grafana is enabled" + profile_grafana_command="--profile grafana" + playground state set flags.ENABLE_JMX_GRAFANA 1 +fi + +docker compose ${profile_grafana_command} up -d \ No newline at end of file diff --git a/flink/flink_session_sql_mode/stop.sh b/flink/flink_session_sql_mode/stop.sh index 92b92d34a0..44c0c049e3 100755 --- a/flink/flink_session_sql_mode/stop.sh +++ b/flink/flink_session_sql_mode/stop.sh @@ -3,6 +3,16 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -docker-compose down -v --remove-orphans +profile_grafana_command="" +if [ -z "$ENABLE_JMX_GRAFANA" ] +then + log "🛑 Grafana is disabled" +else + log "📊 Grafana is enabled" + profile_grafana_command="--profile grafana" + playground state set flags.ENABLE_JMX_GRAFANA 1 +fi + +docker-compose ${profile_grafana_command} down -v --remove-orphans stop_all "$DIR" \ No newline at end of file diff --git a/scripts/flink_download_connectors.sh b/scripts/flink_download_connectors.sh index bf5cde2f73..034041921c 100755 --- a/scripts/flink_download_connectors.sh +++ b/scripts/flink_download_connectors.sh @@ -1,139 +1,145 @@ #!/bin/bash -log() { - echo "$@" +logging() { + log "$@" } - -log "❗ Do you need to install any Flink connectors? (yes/no)" -read need_connectors - -if [[ "$need_connectors" != "yes" ]]; then - log "Skipping connector installation steps." +# Allow users to provide URL for what to download +if [ -n "$FLINK_URL" ]; then + logging "❗ Downloading connectors from $FLINK_URL, full command executed will be 'wget -P /opt/flink/lib $FLINK_URL' " + flink_connectors="wget -P /opt/flink/lib $FLINK_URL && " + export flink_connectors else - log "❗ Is it one connector or multiple connectors? (one/multiple)" - read connector_count + logging "❗ Do you need to install any Flink connectors? (yes/no)" + read need_connectors - if [[ "$connector_count" == "one" ]]; then - log "Please type one word that's related to the connector name:" - read keyword - keywords=("$keyword") + if [[ "$need_connectors" != "yes" ]]; then + logging "Skipping connector installation steps." else - log "Please type multiple words related to the connector names (separated by spaces):" - read -a keywords - fi + logging "❗ Is it one connector or multiple connectors? (one/multiple)" + read connector_count - # Function to fetch connector list - get_connectors() { - curl -s https://repo.maven.apache.org/maven2/org/apache/flink/ | awk -F '"' '/href/ {print $2}' | sed 's:/$::' | sort -u - } + if [[ "$connector_count" == "one" ]]; then + logging "Please type one word that's related to the connector name:" + read keyword + keywords=("$keyword") + else + logging "Please type multiple words related to the connector names (separated by spaces):" + read -a keywords + fi - connector_list=$(get_connectors) - selected_connectors=() + # Function to fetch connector list + get_connectors() { + curl -s https://repo.maven.apache.org/maven2/org/apache/flink/ | awk -F '"' '/href/ {print $2}' | sed 's:/$::' | sort -u + } - # Loop through each keyword - for keyword in "${keywords[@]}"; do - matches=$(echo "$connector_list" | grep -i "$keyword") - if [[ -z "$matches" ]]; then - log "No connectors found matching '$keyword'." - continue - fi - log "Connectors matching '$keyword':" - i=1 - match_list=() - while IFS= read -r line; do - echo "$i) $line" - match_list+=("$line") - ((i++)) - done <<< "$matches" + connector_list=$(get_connectors) + selected_connectors=() - log "Please select connectors by numbers (separated by spaces):" - read selection - IFS=' ' read -r -a selections <<< "$selection" - for sel in "${selections[@]}"; do - if [[ $sel -le ${#match_list[@]} && $sel -ge 1 ]]; then - selected_connector=${match_list[$((sel - 1))]} - selected_connectors+=("$selected_connector") - log "Selected connector: $selected_connector" - else - log "Invalid selection: $sel" + # Loop through each keyword + for keyword in "${keywords[@]}"; do + matches=$(echo "$connector_list" | grep -i "$keyword") + if [[ -z "$matches" ]]; then + logging "No connectors found matching '$keyword'." + continue fi + logging "Connectors matching '$keyword':" + i=1 + match_list=() + while IFS= read -r line; do + echo "$i) $line" + match_list+=("$line") + ((i++)) + done <<< "$matches" + + logging "Please select connectors by numbers (separated by spaces):" + read selection + IFS=' ' read -r -a selections <<< "$selection" + for sel in "${selections[@]}"; do + if [[ $sel -le ${#match_list[@]} && $sel -ge 1 ]]; then + selected_connector=${match_list[$((sel - 1))]} + selected_connectors+=("$selected_connector") + logging "Selected connector: $selected_connector" + else + logging "Invalid selection: $sel" + fi + done done - done - - connector_urls=() - - # Loop through each selected connector - for connector in "${selected_connectors[@]}"; do - log "Fetching versions for connector: $connector" - connector_url="https://repo.maven.apache.org/maven2/org/apache/flink/$connector/" - versions=$(curl -s "$connector_url" | awk -F '"' '/href/ {print $2}' | sed 's:/$::' | sort -u) - if [[ -z "$versions" ]]; then - log "No versions found for connector '$connector'." - continue - fi - log "Available versions for $connector:" - i=1 - version_list=() - while IFS= read -r version; do - echo "$i) $version" - version_list+=("$version") - ((i++)) - done <<< "$versions" - - log "Please select a version by number for connector $connector:" - read version_selection - if [[ $version_selection -le ${#version_list[@]} && $version_selection -ge 1 ]]; then - selected_version=${version_list[$((version_selection - 1))]} - else - log "Invalid selection. Skipping connector $connector." - continue - fi - # Fetch jar files for the selected version - jar_url="$connector_url$selected_version/" - log "Fetching jar files for $connector version $selected_version" - jar_files=$(curl -s "$jar_url" | awk -F '"' '/href/ {print $2}' | grep -E '\.jar$' | sort -u) - if [[ -z "$jar_files" ]]; then - log "No jar files found for $connector version $selected_version." - continue - fi - log "Available jar files for $connector version $selected_version:" - i=1 - jar_list=() - while IFS= read -r jar; do - echo "$i) $jar" - jar_list+=("$jar") - ((i++)) - done <<< "$jar_files" + connector_urls=() - log "❗ Please select jar files by numbers (separated by spaces), or type ⭐'complete'⭐ to finish selection:" - read jar_selection - if [[ "$jar_selection" == "complete" ]]; then - continue - fi - IFS=' ' read -r -a jar_selections <<< "$jar_selection" - for js in "${jar_selections[@]}"; do - if [[ $js -le ${#jar_list[@]} && $js -ge 1 ]]; then - selected_jar=${jar_list[$((js - 1))]} - full_url="$jar_url$selected_jar" - connector_urls+=("$full_url") - log "Selected jar file: $selected_jar" + # Loop through each selected connector + for connector in "${selected_connectors[@]}"; do + logging "Fetching versions for connector: $connector" + connector_url="https://repo.maven.apache.org/maven2/org/apache/flink/$connector/" + versions=$(curl -s "$connector_url" | awk -F '"' '/href/ {print $2}' | sed 's:/$::' | sort -u) + if [[ -z "$versions" ]]; then + logging "No versions found for connector '$connector'." + continue + fi + logging "Available versions for $connector:" + i=1 + version_list=() + while IFS= read -r version; do + echo "$i) $version" + version_list+=("$version") + ((i++)) + done <<< "$versions" + + logging "Please select a version by number for connector $connector:" + read version_selection + if [[ $version_selection -le ${#version_list[@]} && $version_selection -ge 1 ]]; then + selected_version=${version_list[$((version_selection - 1))]} else - log "Invalid selection: $js" + logging "Invalid selection. Skipping connector $connector." + continue + fi + + # Fetch jar files for the selected version + jar_url="$connector_url$selected_version/" + logging "Fetching jar files for $connector version $selected_version" + jar_files=$(curl -s "$jar_url" | awk -F '"' '/href/ {print $2}' | grep -E '\.jar$' | sort -u) + if [[ -z "$jar_files" ]]; then + logging "No jar files found for $connector version $selected_version." + continue + fi + logging "Available jar files for $connector version $selected_version:" + i=1 + jar_list=() + while IFS= read -r jar; do + echo "$i) $jar" + jar_list+=("$jar") + ((i++)) + done <<< "$jar_files" + + logging "❗ Please select jar files by numbers (separated by spaces), or type 'complete' to finish selection:" + read jar_selection + if [[ "$jar_selection" == "complete" ]]; then + continue fi + IFS=' ' read -r -a jar_selections <<< "$jar_selection" + for js in "${jar_selections[@]}"; do + if [[ $js -le ${#jar_list[@]} && $js -ge 1 ]]; then + selected_jar=${jar_list[$((js - 1))]} + full_url="$jar_url$selected_jar" + connector_urls+=("$full_url") + logging "Selected jar file: $selected_jar" + else + logging "Invalid selection: $js" + fi + done done - done - # Set the environment variable 'connectors' - if [ -z "${connector_urls[*]}" ]; then - flink_connectors=" " - else - flink_connectors="wget -P /opt/flink/lib ${connector_urls[*]} && " - fi - export flink_connectors + # Set the environment variable 'connectors' + if [ -z "${connector_urls[*]}" ]; then + flink_connectors=" " + else + flink_connectors="wget -P /opt/flink/lib ${connector_urls[*]} && " + fi + export flink_connectors - log "Environment variable 'flink_connectors' set with the following URLs which will be downloaded for the containers:" - log "$flink_connectors" + logging "Environment variable 'flink_connectors' set with the following URLs which will be downloaded for the containers:" + logging "$flink_connectors" + fi fi -log "Script completed." \ No newline at end of file +logging "Script completed." \ No newline at end of file diff --git a/scripts/utils.sh b/scripts/utils.sh index 51460a7ba0..3f271dd124 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -125,6 +125,7 @@ then export GRAFANA_AGENT_CONSUMER="" export GRAFANA_AGENT_SR="" export GRAFANA_AGENT_KSQLDB="" + export GRAFANA_FLINK="" else export GRAFANA_AGENT_ZK="-javaagent:/usr/share/jmx_exporter/pyroscope-0.11.2.jar -javaagent:/usr/share/jmx_exporter/jmx_prometheus_javaagent-0.20.0.jar=1234:/usr/share/jmx_exporter/zookeeper.yml" export GRAFANA_AGENT_BROKER="-javaagent:/usr/share/jmx_exporter/pyroscope-0.11.2.jar -javaagent:/usr/share/jmx_exporter/jmx_prometheus_javaagent-0.20.0.jar=1234:/usr/share/jmx_exporter/kafka_broker.yml" @@ -133,6 +134,8 @@ else export GRAFANA_AGENT_CONSUMER="-javaagent:/usr/share/jmx_exporter/pyroscope-0.11.2.jar -javaagent:/usr/share/jmx_exporter/jmx_prometheus_javaagent-0.20.0.jar=1234:/usr/share/jmx_exporter/kafka-consumer.yml" export GRAFANA_AGENT_SR="-javaagent:/usr/share/jmx_exporter/pyroscope-0.11.2.jar -javaagent:/usr/share/jmx_exporter/jmx_prometheus_javaagent-0.20.0.jar=1234:/usr/share/jmx_exporter/confluent_schemaregistry.yml" export GRAFANA_AGENT_KSQLDB="-javaagent:/usr/share/jmx_exporter/pyroscope-0.11.2.jar -javaagent:/usr/share/jmx_exporter/jmx_prometheus_javaagent-0.20.0.jar=1234:/usr/share/jmx_exporter/confluent_ksql.yml" + export GRAFANA_FLINK="metrics.reporter.prom.factory.class: org.apache.flink.metrics.prometheus.PrometheusReporterFactory + metrics.reporter.prom.port: 9090" fi # Migrate SimpleAclAuthorizer to AclAuthorizer #1276 From 6aeffa981f4b4f0da1dbc82eb350fb7a833d5564 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 27 Nov 2024 15:31:11 +0100 Subject: [PATCH 062/659] fully-managed-mqtt-source-mtls.sh --- scripts/tests-ignored.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/tests-ignored.txt b/scripts/tests-ignored.txt index ee97c1f6b9..e1e71c3121 100644 --- a/scripts/tests-ignored.txt +++ b/scripts/tests-ignored.txt @@ -20,4 +20,7 @@ snowflake-sink-snowpipe-streaming.sh # no need to test in CI azure-cognitive-search-sink-proxy.sh -s3-sink-with-short-lived-creds.sh \ No newline at end of file +s3-sink-with-short-lived-creds.sh + +# hostname validation +fully-managed-mqtt-source-mtls.sh \ No newline at end of file From 689928c8ebde2ca196baaf87728b3bac4a6e00f0 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 27 Nov 2024 15:31:23 +0100 Subject: [PATCH 063/659] wip --- scripts/cli/tag-list.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/cli/tag-list.txt b/scripts/cli/tag-list.txt index 925fd165c9..d24925d35d 100644 --- a/scripts/cli/tag-list.txt +++ b/scripts/cli/tag-list.txt @@ -52,7 +52,6 @@ 5.5.7 5.5.8 5.5.9 -6.0.0 6.0.1 6.0.10 6.0.11 @@ -76,6 +75,7 @@ 6.1.13 6.1.14 6.1.15 +6.1.2 6.1.3 6.1.4 6.1.5 @@ -123,6 +123,7 @@ 7.1.12 7.1.13 7.1.14 +7.1.15 7.1.2 7.1.3 7.1.4 @@ -163,6 +164,7 @@ 7.4.5 7.4.6 7.4.7 +7.4.8 7.5.0 7.5.1 7.5.2 From 965b3e232d955ec9e2a1626cde37930b240f9a65 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 29 Nov 2024 14:24:30 +0100 Subject: [PATCH 064/659] 7.7.2 --- scripts/cli/tag-list.txt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/scripts/cli/tag-list.txt b/scripts/cli/tag-list.txt index d24925d35d..6e1245e15a 100644 --- a/scripts/cli/tag-list.txt +++ b/scripts/cli/tag-list.txt @@ -27,8 +27,7 @@ 5.3.8-1 5.3.8-2 5.4.0 -5.4.0-beta1 -5.4.0-beta1-1 +5.4.0-beta15.4.0-beta1-1 5.4.1 5.4.10 5.4.2 @@ -50,8 +49,8 @@ 5.5.5 5.5.6 5.5.7 -5.5.8 5.5.9 +6.0.0 6.0.1 6.0.10 6.0.11 @@ -84,7 +83,6 @@ 6.1.8 6.1.9 6.2.0 -6.2.1 6.2.10 6.2.11 6.2.12 @@ -137,6 +135,7 @@ 7.2.10 7.2.11 7.2.12 +7.2.13 7.2.2 7.2.3 7.2.4 @@ -148,6 +147,7 @@ 7.3.0 7.3.1 7.3.10 +7.3.11 7.3.2 7.3.3 7.3.4 @@ -172,9 +172,12 @@ 7.5.4 7.5.5 7.5.6 +7.5.7 7.6.0 7.6.1 7.6.2 7.6.3 +7.6.4 7.7.0 7.7.1 +7.7.2 From b6597ebcb0468e2260e719ef780fcccb4ec77c78 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 29 Nov 2024 16:40:03 +0100 Subject: [PATCH 065/659] 7.7.2 --- scripts/utils.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/utils.sh b/scripts/utils.sh index 3f271dd124..62cbc119a7 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -33,7 +33,7 @@ fi if [ -z "$TAG" ] then # TAG is not set, use default: - export TAG=7.7.1 # default tag + export TAG=7.7.2 # default tag # to handle ubi8 images export TAG_BASE=$TAG if [ -z "$CP_KAFKA_IMAGE" ] From 0da74bd75cad5051fe9c3a1ab54874b5ceadc757 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 2 Dec 2024 13:50:28 +0100 Subject: [PATCH 066/659] Add schema metadata support to playground schema register #6006 --- scripts/cli/completions.bash | 2 +- scripts/cli/playground | 34 +++++++++++++++++++++ scripts/cli/playground.json | 7 +++++ scripts/cli/playground.yaml | 14 +++++++++ scripts/cli/src/bashly.yml | 13 ++++++++ scripts/cli/src/commands/schema/register.sh | 10 ++++++ 6 files changed, 79 insertions(+), 1 deletion(-) diff --git a/scripts/cli/completions.bash b/scripts/cli/completions.bash index a6874380e9..01399aa3f4 100644 --- a/scripts/cli/completions.bash +++ b/scripts/cli/completions.bash @@ -1041,7 +1041,7 @@ _playground_completions() { ;; *'schema register'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --schema --subject --verbose -h -v")" -- "$cur") + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --metadata-property --schema --subject --verbose -h -v")" -- "$cur") ;; *'debug heap-dump'*) diff --git a/scripts/cli/playground b/scripts/cli/playground index 882660a62b..0eaae310ad 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -2366,6 +2366,11 @@ playground_schema_register_usage() { printf " ☢️ Force schema id\n \n ❗it will replace any schema which already exists at given id\n" echo + # :flag.usage + printf " %s\n" "$(magenta "--metadata-property METADATA-PROPERTY (repeatable)")" + printf " 🟡 Add metadata properties to schema contract\n \n See docs:\n https://docs.confluent.io/platform/current/schema-registry/fundamentals/data-contracts.html#metadata-properties\n \n 🎓 Tip: you can pass multiple properties by specifying --metadata-property\n multiple times\n \n Example: --metadata-property \"metadata1=value\" --metadata-property\n \"metadata2=value\"\n" + echo + # :command.usage_fixed_flags printf " %s\n" "$(magenta "--help, -h")" printf " Show this help\n" @@ -17858,6 +17863,7 @@ playground_schema_register_command() { id="${args[--id]}" verbose="${args[--verbose]}" + eval "metadata_property=(${args[--metadata-property]})" get_sr_url_and_security tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) @@ -17919,6 +17925,15 @@ playground_schema_register_command() { json_new=$(echo $json | jq --arg content "$content" '. + { "schema": $content }') fi + # Check if the array contains multiple results + if [ "${#metadata_property[@]}" -gt 1 ] + then + log "🟡 schema metadata are present, adding them" + # Construct metadata_json using jq + metadata_json=$(jq -n --argjson props "$(printf '%s\n' "${metadata_property[@]}" | jq -R 'split("=") | { (.[0]): .[1] }' | jq -s 'add')" '{properties: $props}') + json_new=$(echo $json_new | jq --argjson metadata "$metadata_json" '. + { "metadata": $metadata }') + fi + if [[ -n "$id" ]] then function set_back_read_write { @@ -30368,6 +30383,25 @@ playground_schema_register_parse_requirements() { fi ;; + # :flag.case + --metadata-property) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + escaped="$(printf '%q' "$2")" + if [[ -z ${args['--metadata-property']+x} ]]; then + args['--metadata-property']="$escaped" + else + args['--metadata-property']="${args['--metadata-property']} $escaped" + fi + shift + shift + else + printf "%s\n" "--metadata-property requires an argument: --metadata-property METADATA-PROPERTY" >&2 + exit 1 + fi + ;; + -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index 3400b26ed6..0fa67f4ee2 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -613,6 +613,13 @@ ], "argument": "ID", "description": "☢️ Force schema id\n\n❗it will replace any schema which already exists at given id\n" + }, + { + "names": [ + "--metadata-property" + ], + "argument": "METADATA-PROPERTY", + "description": "🟡 Add metadata properties to schema contract\n\nSee docs: https://docs.confluent.io/platform/current/schema-registry/fundamentals/data-contracts.html#metadata-properties\n\n🎓 Tip: you can pass multiple properties by specifying --metadata-property multiple times\n\nExample: --metadata-property \"metadata1=value\" --metadata-property \"metadata2=value\"\n\nRepeatable: ✓ Yes\n" } ] }, diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index 3f047bbe20..3aa80e67ba 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -747,6 +747,20 @@ subcommands: ❗it will replace any schema which already exists at given id + - names: + - --metadata-property + argument: METADATA-PROPERTY + description: | + 🟡 Add metadata properties to schema contract + + See docs: https://docs.confluent.io/platform/current/schema-registry/fundamentals/data-contracts.html#metadata-properties + + 🎓 Tip: you can pass multiple properties by specifying --metadata-property multiple times + + Example: --metadata-property "metadata1=value" --metadata-property "metadata2=value" + + Repeatable: ✓ Yes + - name: get-compatibility description: | 🛡️ Get subject-level compatibility diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index f2280c265a..d45d2a0b8d 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -1182,6 +1182,19 @@ commands: ❗it will replace any schema which already exists at given id + - long: --metadata-property + arg: metadata-property + help: |- + 🟡 Add metadata properties to schema contract + + See docs: https://docs.confluent.io/platform/current/schema-registry/fundamentals/data-contracts.html#metadata-properties + + 🎓 Tip: you can pass multiple properties by specifying --metadata-property multiple times + + Example: --metadata-property "metadata1=value" --metadata-property "metadata2=value" + required: false + repeatable: true + examples: | playground schema register --subject test-protobuf << 'EOF' syntax = "proto3"; diff --git a/scripts/cli/src/commands/schema/register.sh b/scripts/cli/src/commands/schema/register.sh index 8fbf385e4d..2383de2120 100644 --- a/scripts/cli/src/commands/schema/register.sh +++ b/scripts/cli/src/commands/schema/register.sh @@ -3,6 +3,7 @@ schema="${args[--schema]}" id="${args[--id]}" verbose="${args[--verbose]}" +eval "metadata_property=(${args[--metadata-property]})" get_sr_url_and_security tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) @@ -64,6 +65,15 @@ else json_new=$(echo $json | jq --arg content "$content" '. + { "schema": $content }') fi +# Check if the array contains multiple results +if [ "${#metadata_property[@]}" -gt 1 ] +then + log "🟡 schema metadata are present, adding them" + # Construct metadata_json using jq + metadata_json=$(jq -n --argjson props "$(printf '%s\n' "${metadata_property[@]}" | jq -R 'split("=") | { (.[0]): .[1] }' | jq -s 'add')" '{properties: $props}') + json_new=$(echo $json_new | jq --argjson metadata "$metadata_json" '. + { "metadata": $metadata }') +fi + if [[ -n "$id" ]] then function set_back_read_write { From c14245aca3578924078c3c98b3864264263e53ef Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 2 Dec 2024 14:13:06 +0100 Subject: [PATCH 067/659] fully-managed-http-v2-sink-mtls-auth.sh --- scripts/tests-ignored.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/tests-ignored.txt b/scripts/tests-ignored.txt index e1e71c3121..f2d73f6083 100644 --- a/scripts/tests-ignored.txt +++ b/scripts/tests-ignored.txt @@ -23,4 +23,5 @@ azure-cognitive-search-sink-proxy.sh s3-sink-with-short-lived-creds.sh # hostname validation -fully-managed-mqtt-source-mtls.sh \ No newline at end of file +fully-managed-mqtt-source-mtls.sh +fully-managed-http-v2-sink-mtls-auth.sh \ No newline at end of file From b1cf1e49e7d881d49f958cc7762bae652e1b722b Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 2 Dec 2024 14:13:16 +0100 Subject: [PATCH 068/659] update --- scripts/cli/playground | 2 +- scripts/cli/src/bashly.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 0eaae310ad..46b8377f3a 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -2378,7 +2378,7 @@ playground_schema_register_usage() { # :command.usage_examples printf "%s\n" "$(bold "Examples")" - printf " playground schema register --subject test-protobuf << 'EOF'\n syntax = \"proto3\";\n \n package com.github.vdesabou;\n \n message Customer {\n int64 count = 1;\n string first_name = 2;\n string last_name = 3;\n string address = 4;\n }\n EOF\n \n playground schema register --subject test-avro << 'EOF'\n {\n \"type\": \"record\",\n \"namespace\": \"com.github.vdesabou\",\n \"name\": \"Customer\",\n \"fields\": [\n {\n \"name\": \"count\",\n \"type\": \"long\",\n \"doc\": \"count\"\n },\n {\n \"name\": \"first_name\",\n \"type\": \"string\",\n \"doc\": \"First Name of Customer\"\n },\n {\n \"name\": \"last_name\",\n \"type\": \"string\",\n \"doc\": \"Last Name of Customer\"\n },\n {\n \"name\": \"address\",\n \"type\": \"string\",\n \"doc\": \"Address of Customer\"\n }\n ]\n }\n EOF\n" + printf " playground schema register --subject test-protobuf << 'EOF'\n syntax = \"proto3\";\n \n package com.github.vdesabou;\n \n message Customer {\n int64 count = 1;\n string first_name = 2;\n string last_name = 3;\n string address = 4;\n }\n EOF\n \n playground schema register --subject test-avro --metadata-property test=test\n --metadata-property test2=test << 'EOF'\n {\n \"type\": \"record\",\n \"namespace\": \"com.github.vdesabou\",\n \"name\": \"Customer\",\n \"fields\": [\n {\n \"name\": \"count\",\n \"type\": \"long\",\n \"doc\": \"count\"\n },\n {\n \"name\": \"first_name\",\n \"type\": \"string\",\n \"doc\": \"First Name of Customer\"\n },\n {\n \"name\": \"last_name\",\n \"type\": \"string\",\n \"doc\": \"Last Name of Customer\"\n },\n {\n \"name\": \"address\",\n \"type\": \"string\",\n \"doc\": \"Address of Customer\"\n }\n ]\n }\n EOF\n" echo fi diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index d45d2a0b8d..d587d3f59f 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -1209,7 +1209,7 @@ commands: } EOF - playground schema register --subject test-avro << 'EOF' + playground schema register --subject test-avro --metadata-property test=test --metadata-property test2=test << 'EOF' { "type": "record", "namespace": "com.github.vdesabou", From 039ec51de1912b830c7cc054662f2bab8a4ccdb9 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 2 Dec 2024 15:34:52 +0100 Subject: [PATCH 069/659] 7.7.2 --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 83b5182809..ea1b78602e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: strategy: fail-fast: false matrix: - tag: ["7.7.1"] + tag: ["7.7.2"] test_list : [ # requiring ngrok "🚀1️⃣ ccloud/fm-debezium-mysql-legacy-source ccloud/fm-debezium-postgresql-legacy-source ccloud/fm-debezium-mysql-v2-source ccloud/fm-debezium-sqlserver-legacy-source ccloud/fm-debezium-sqlserver-v2-source ccloud/fm-elasticsearch-sink ccloud/fm-jdbc-sqlserver-sink ccloud/fm-jdbc-sqlserver-source ccloud/fm-ibm-mq-source ccloud/fm-jdbc-mysql-source ccloud/fm-jdbc-postgresql-sink ccloud/fm-mqtt-source ccloud/fm-debezium-postgresql-v2-source ccloud/fm-jdbc-postgresql-source", @@ -326,7 +326,7 @@ jobs: strategy: fail-fast: false matrix: - tag: ["7.7.1"] + tag: ["7.7.2"] test_list : [ "🚀 ${{ github.event.inputs.test_name }}" ] @@ -595,7 +595,7 @@ jobs: - name: Update README run: | cd ./scripts/cli - ./playground update-readme --tags "7.7.1" + ./playground update-readme --tags "7.7.2" env: GH_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} From cd184b9797350dba565e54dfd9ef2a21510eeaea Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 2 Dec 2024 16:14:10 +0100 Subject: [PATCH 070/659] fix WARN for flink_connectors --- scripts/cli/playground | 1 + scripts/cli/src/lib/utils_function.sh | 1 + scripts/flink_download_connectors.sh | 1 + 3 files changed, 3 insertions(+) diff --git a/scripts/cli/playground b/scripts/cli/playground index 46b8377f3a..cbdecdf387 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8581,6 +8581,7 @@ function set_profiles() { then log "🛑 Starting services without Flink" playground state del flags.ENABLE_FLINK + export flink_connectors="" else log "🐿️ Starting services with Flink" profile_flink="--profile flink" diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index d910f7dcb4..be650eac23 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -499,6 +499,7 @@ function set_profiles() { then log "🛑 Starting services without Flink" playground state del flags.ENABLE_FLINK + export flink_connectors="" else log "🐿️ Starting services with Flink" profile_flink="--profile flink" diff --git a/scripts/flink_download_connectors.sh b/scripts/flink_download_connectors.sh index 034041921c..d4dadb3558 100755 --- a/scripts/flink_download_connectors.sh +++ b/scripts/flink_download_connectors.sh @@ -9,6 +9,7 @@ if [ -n "$FLINK_URL" ]; then flink_connectors="wget -P /opt/flink/lib $FLINK_URL && " export flink_connectors else + export flink_connectors="" logging "❗ Do you need to install any Flink connectors? (yes/no)" read need_connectors From 936e41aad8c2283ff0eff08ebcdd38fa0b6624f1 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 2 Dec 2024 16:17:58 +0100 Subject: [PATCH 071/659] 7.8.0 --- scripts/cli/tag-list.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/cli/tag-list.txt b/scripts/cli/tag-list.txt index 6e1245e15a..a87f9d6be5 100644 --- a/scripts/cli/tag-list.txt +++ b/scripts/cli/tag-list.txt @@ -27,7 +27,8 @@ 5.3.8-1 5.3.8-2 5.4.0 -5.4.0-beta15.4.0-beta1-1 +5.4.0-beta1 +5.4.0-beta1-1 5.4.1 5.4.10 5.4.2 @@ -49,11 +50,11 @@ 5.5.5 5.5.6 5.5.7 +5.5.8 5.5.9 6.0.0 6.0.1 6.0.10 -6.0.11 6.0.12 6.0.13 6.0.14 @@ -62,7 +63,6 @@ 6.0.3 6.0.4 6.0.5 -6.0.6 6.0.7 6.0.8 6.0.9 @@ -79,12 +79,11 @@ 6.1.4 6.1.5 6.1.6 -6.1.7 6.1.8 6.1.9 6.2.0 +6.2.1 6.2.10 -6.2.11 6.2.12 6.2.13 6.2.14 @@ -181,3 +180,4 @@ 7.7.0 7.7.1 7.7.2 +7.8.0 From b2911204b7b1fe9dcb00deb67d14b8684d879cd2 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 2 Dec 2024 16:21:08 +0100 Subject: [PATCH 072/659] 7.8.0 --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea1b78602e..8b1ec34a9b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: strategy: fail-fast: false matrix: - tag: ["7.7.2"] + tag: ["7.8.0"] test_list : [ # requiring ngrok "🚀1️⃣ ccloud/fm-debezium-mysql-legacy-source ccloud/fm-debezium-postgresql-legacy-source ccloud/fm-debezium-mysql-v2-source ccloud/fm-debezium-sqlserver-legacy-source ccloud/fm-debezium-sqlserver-v2-source ccloud/fm-elasticsearch-sink ccloud/fm-jdbc-sqlserver-sink ccloud/fm-jdbc-sqlserver-source ccloud/fm-ibm-mq-source ccloud/fm-jdbc-mysql-source ccloud/fm-jdbc-postgresql-sink ccloud/fm-mqtt-source ccloud/fm-debezium-postgresql-v2-source ccloud/fm-jdbc-postgresql-source", @@ -326,7 +326,7 @@ jobs: strategy: fail-fast: false matrix: - tag: ["7.7.2"] + tag: ["7.8.0"] test_list : [ "🚀 ${{ github.event.inputs.test_name }}" ] @@ -595,7 +595,7 @@ jobs: - name: Update README run: | cd ./scripts/cli - ./playground update-readme --tags "7.7.2" + ./playground update-readme --tags "7.8.0" env: GH_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} From 7eafab785556cbb0b09da9248bc709476ee1f7c9 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 2 Dec 2024 16:21:16 +0100 Subject: [PATCH 073/659] 7.8.0 --- scripts/cli/src/lib/utils_function.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index be650eac23..3a54d1d102 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -113,6 +113,11 @@ function version_gt() { function set_kafka_client_tag() { + if [[ $TAG_BASE = 7.8.* ]] + then + export KAFKA_CLIENT_TAG="3.8.0" + fi + if [[ $TAG_BASE = 7.7.* ]] then export KAFKA_CLIENT_TAG="3.7.0" From ca1018e069d496e1558146a7a0413d8fca6259a0 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 3 Dec 2024 12:09:04 +0100 Subject: [PATCH 074/659] 4.0.0 --- scripts/cli/playground | 4 ++-- scripts/cli/src/lib/utils_function.sh | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index cbdecdf387..ff2dd019aa 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -10195,7 +10195,7 @@ function wait_for_log () { } -CLI_MIN_VERSION=${CLI_MIN_VERSION:-2.5.0} +CLI_MIN_VERSION=${CLI_MIN_VERSION:-4.0.0} # -------------------------------------------------------------- # Library @@ -11015,7 +11015,7 @@ function ccloud::set_kafka_cluster_use() { # https://docs.confluent.io/platform/current/tutorials/examples/ccloud/docs/ccloud-stack.html # function ccloud::create_ccloud_stack() { - #ccloud::validate_version_cli $CLI_MIN_VERSION || exit 1 + ccloud::validate_version_cli $CLI_MIN_VERSION || exit 1 QUIET="${QUIET:-false}" REPLICATION_FACTOR=${REPLICATION_FACTOR:-3} enable_ksqldb=${1:-false} diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 3a54d1d102..7b98170b32 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -622,7 +622,7 @@ function get_ansible_version() { } function check_confluent_version() { - REQUIRED_CONFLUENT_VER=${1:-"3.0.0"} + REQUIRED_CONFLUENT_VER=${1:-"4.0.0"} CONFLUENT_VER=$(get_confluent_version) if version_gt $REQUIRED_CONFLUENT_VER $CONFLUENT_VER; then @@ -1711,7 +1711,7 @@ function maybe_delete_ccloud_environment () { # log "🧹❌ Confluent Cloud cluster will be deleted..." verify_installed "confluent" - check_confluent_version 2.0.0 || exit 1 + check_confluent_version 4.0.0 || exit 1 verify_confluent_login "confluent kafka cluster list" export QUIET=true @@ -2125,7 +2125,7 @@ function wait_for_log () { -CLI_MIN_VERSION=${CLI_MIN_VERSION:-2.5.0} +CLI_MIN_VERSION=${CLI_MIN_VERSION:-4.0.0} # -------------------------------------------------------------- # Library @@ -2953,7 +2953,7 @@ function ccloud::set_kafka_cluster_use() { # https://docs.confluent.io/platform/current/tutorials/examples/ccloud/docs/ccloud-stack.html # function ccloud::create_ccloud_stack() { - #ccloud::validate_version_cli $CLI_MIN_VERSION || exit 1 + ccloud::validate_version_cli $CLI_MIN_VERSION || exit 1 QUIET="${QUIET:-false}" REPLICATION_FACTOR=${REPLICATION_FACTOR:-3} enable_ksqldb=${1:-false} From 81a147535da6ad589930003519e17361506f42a5 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 4 Dec 2024 10:51:10 +0100 Subject: [PATCH 075/659] "topic.creation.groups": "redo" --- connect/connect-cdc-oracle11-source/cdc-oracle11-source.sh | 1 + .../connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh | 1 + .../connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh | 1 + connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table.sh | 1 + .../cdc-oracle12-pdb-table-mtls-db-auth.sh | 1 + .../connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh | 1 + .../connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh | 1 + connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table.sh | 1 + .../connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh | 1 + .../connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh | 1 + connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table.sh | 1 + .../connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh | 1 + .../connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh | 1 + connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table.sh | 1 + .../connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh | 1 + .../connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh | 1 + connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh | 1 + connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-mview.sh | 1 + .../cdc-oracle19-pdb-table-mtls-db-auth.sh | 1 + .../connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh | 1 + .../connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh | 1 + connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh | 1 + .../connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh | 1 + .../connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh | 1 + connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh | 1 + connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-mview.sh | 1 + .../cdc-oracle21-pdb-table-mtls-db-auth.sh | 1 + .../connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh | 1 + connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table.sh | 1 + 29 files changed, 29 insertions(+) diff --git a/connect/connect-cdc-oracle11-source/cdc-oracle11-source.sh b/connect/connect-cdc-oracle11-source/cdc-oracle11-source.sh index 963095b8aa..45fb030da4 100755 --- a/connect/connect-cdc-oracle11-source/cdc-oracle11-source.sh +++ b/connect/connect-cdc-oracle11-source/cdc-oracle11-source.sh @@ -103,6 +103,7 @@ playground connector create-or-update --connector cdc-oracle11-source --package "numeric.mapping": "best_fit", "connection.pool.max.size": 20, "redo.log.row.fetch.size": 1, + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh index c58421fd08..a224ae0170 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh @@ -233,6 +233,7 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "numeric.mapping": "best_fit", "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh index 3c19370e25..63f12f0bff 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh @@ -203,6 +203,7 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "numeric.mapping": "best_fit", "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table.sh index bf61ad88da..296b0160fb 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table.sh @@ -138,6 +138,7 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "numeric.mapping": "best_fit", "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh index dcd00f601d..31678544b6 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh @@ -255,6 +255,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "numeric.mapping": "best_fit", "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh index 30f26afc84..157db023b8 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh @@ -248,6 +248,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "numeric.mapping": "best_fit", "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh index 3051fd105c..0a7c9e1000 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh @@ -216,6 +216,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "numeric.mapping": "best_fit", "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table.sh index a96de445d8..8189adfde7 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table.sh @@ -151,6 +151,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "numeric.mapping": "best_fit", "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh index 45c1d4c3cd..5702f1705c 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh @@ -235,6 +235,7 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "numeric.mapping": "best_fit", "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh index 7b0d67b127..8e682cf74d 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh @@ -203,6 +203,7 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "numeric.mapping": "best_fit", "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table.sh index 6a54d8f278..be2fa38a85 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table.sh @@ -138,6 +138,7 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "numeric.mapping": "best_fit", "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh index eb201d87a8..5dfa5e6ad7 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh @@ -248,6 +248,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "numeric.mapping": "best_fit", "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh index cc1205887e..7d26caae7d 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh @@ -216,6 +216,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "numeric.mapping": "best_fit", "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table.sh index 54193c8b3c..12a17421de 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table.sh @@ -151,6 +151,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "numeric.mapping": "best_fit", "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh index 723dd75d25..e8b6c5b33d 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh @@ -229,6 +229,7 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh index 2a54cad840..e84accffac 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh @@ -200,6 +200,7 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh index bdde442550..aef37588f3 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh @@ -136,6 +136,7 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-mview.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-mview.sh index 30d840994e..a814e589d1 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-mview.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-mview.sh @@ -139,6 +139,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb-mview -- "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh index 88d26cb7b5..11f76ea4f4 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh @@ -254,6 +254,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh index 48f5c1a717..a33410df02 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh @@ -247,6 +247,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh index 1f6f2a290f..f078d199c3 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh @@ -217,6 +217,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh index d920decabd..9503fb9162 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh @@ -153,6 +153,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh index 6ff4142c9c..f853d0949b 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh @@ -229,6 +229,7 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh index 55c54e44be..4fbfe0b502 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh @@ -199,6 +199,7 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh index 6e2ae14e86..8b6f22a2f8 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh @@ -136,6 +136,7 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-mview.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-mview.sh index 0c523fca83..1bc19723f3 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-mview.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-mview.sh @@ -139,6 +139,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb-mview -- "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh index f056c61946..0c8674ecf9 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh @@ -254,6 +254,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh index bf2b93113d..7face93c17 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh @@ -247,6 +247,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table.sh index 769226cc4d..981bd0375f 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table.sh @@ -153,6 +153,7 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "connection.pool.max.size": 20, "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, "topic.creation.redo.partitions": 1, From f41e5be4f14465fa34acd841772faa4363229603 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 4 Dec 2024 13:45:09 +0100 Subject: [PATCH 076/659] 7.8.0 as default --- scripts/utils.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/utils.sh b/scripts/utils.sh index 62cbc119a7..34d4dbd423 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -33,7 +33,7 @@ fi if [ -z "$TAG" ] then # TAG is not set, use default: - export TAG=7.7.2 # default tag + export TAG=7.8.0 # default tag # to handle ubi8 images export TAG_BASE=$TAG if [ -z "$CP_KAFKA_IMAGE" ] From 59b10624ded7f14873e50a2af7b46ee83408d489 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 4 Dec 2024 13:45:30 +0100 Subject: [PATCH 077/659] use alpine/openssl image --- ...y-managed-debezium-legacy-sqlserver-source-ssl.sh | 4 +++- ...fully-managed-debezium-v2-sqlserver-source-ssl.sh | 2 +- .../fully-managed-mysql-source-ssl.sh | 2 +- .../debezium-postgres-source-mtls.sh | 12 ++++++------ .../debezium-postgres-source-ssl.sh | 6 +++--- .../debezium-sqlserver-source-ssl.sh | 2 +- connect/connect-jdbc-mysql-sink/mysql-sink-mtls.sh | 2 +- connect/connect-jdbc-mysql-sink/mysql-sink-ssl.sh | 2 +- connect/connect-jdbc-mysql-source/mysql-mtls.sh | 2 +- connect/connect-jdbc-mysql-source/mysql-ssl.sh | 2 +- .../postgres-sink-mtls.sh | 12 ++++++------ .../postgres-sink-ssl.sh | 6 +++--- .../connect-jdbc-postgresql-source/postgres-mtls.sh | 12 ++++++------ .../connect-jdbc-postgresql-source/postgres-ssl.sh | 6 +++--- .../sqlserver-jtds-sink-ssl.sh | 2 +- .../sqlserver-microsoft-sink-ssl.sh | 2 +- .../sqlserver-jtds-ssl.sh | 2 +- .../sqlserver-microsoft-ssl.sh | 2 +- connect/connect-mongodb-sink/mongo-sink-ssl.sh | 2 +- connect/connect-mongodb-source/mongo-source-ssl.sh | 2 +- environment/rbac-sasl-plain/start.sh | 6 +++--- reproduction-models | 2 +- 22 files changed, 47 insertions(+), 45 deletions(-) diff --git a/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh b/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh index 0c2e641ac2..98d1a3f522 100755 --- a/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh +++ b/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh @@ -22,7 +22,7 @@ rm -f mssql.key #https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-docker-container-security?view=sql-server-ver15 #https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-encrypted-connections?view=sql-server-ver15&preserve-view=true#client-initiated-encryption log "Create a self-signed certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sqlserver' -keyout /tmp/mssql.key -out /tmp/mssql.pem -days 365 +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sqlserver' -keyout /tmp/mssql.key -out /tmp/mssql.pem -days 365 if [[ "$OSTYPE" == "darwin"* ]] then @@ -98,6 +98,8 @@ do sleep 5 done +sleep 5 + log "Create table" docker exec -i sqlserver /opt/mssql-tools18/bin/sqlcmd -C -No -U sa -P Password! << EOF -- Create the test database diff --git a/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh b/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh index 378c31809f..c9f4e923c3 100755 --- a/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh +++ b/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh @@ -22,7 +22,7 @@ rm -f mssql.key #https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-docker-container-security?view=sql-server-ver15 #https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-encrypted-connections?view=sql-server-ver15&preserve-view=true#client-initiated-encryption log "Create a self-signed certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sqlserver' -keyout /tmp/mssql.key -out /tmp/mssql.pem -days 365 +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sqlserver' -keyout /tmp/mssql.key -out /tmp/mssql.pem -days 365 if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/ccloud/fm-jdbc-mysql-source/fully-managed-mysql-source-ssl.sh b/ccloud/fm-jdbc-mysql-source/fully-managed-mysql-source-ssl.sh index 01ae2a6b3a..41503987fc 100755 --- a/ccloud/fm-jdbc-mysql-source/fully-managed-mysql-source-ssl.sh +++ b/ccloud/fm-jdbc-mysql-source/fully-managed-mysql-source-ssl.sh @@ -46,7 +46,7 @@ else fi docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword # Convert the client key and certificate files to a PKCS #12 archive -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 +docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 # Import the client key and certificate into a Java keystore: docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword cd - diff --git a/connect/connect-debezium-postgresql-source/debezium-postgres-source-mtls.sh b/connect/connect-debezium-postgresql-source/debezium-postgres-source-mtls.sh index 2c62461085..15c5960cf6 100755 --- a/connect/connect-debezium-postgresql-source/debezium-postgres-source-mtls.sh +++ b/connect/connect-debezium-postgresql-source/debezium-postgres-source-mtls.sh @@ -30,11 +30,11 @@ rm -f ca.key #https://blog.crunchydata.com/blog/ssl-certificate-authentication-postgresql-docker-containers log " Creating a Root Certificate Authority (CA)" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -x509 -days 365 -nodes -out /tmp/ca.crt -keyout /tmp/ca.key -subj "/CN=root-ca" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -x509 -days 365 -nodes -out /tmp/ca.crt -keyout /tmp/ca.key -subj "/CN=root-ca" log "Generate the PostgreSQL server key and certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -nodes -out /tmp/server.csr -keyout /tmp/server.key -subj "/CN=postgres" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl x509 -req -in /tmp/server.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/server.crt +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -nodes -out /tmp/server.csr -keyout /tmp/server.key -subj "/CN=postgres" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl x509 -req -in /tmp/server.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/server.crt if [[ "$OSTYPE" == "darwin"* ]] then # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 @@ -48,8 +48,8 @@ fi rm server.csr log "Generating the Client Key and Certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -nodes -out /tmp/client.csr -keyout /tmp/client.key -subj "/CN=myuser" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl x509 -req -in /tmp/client.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/client.crt +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -nodes -out /tmp/client.csr -keyout /tmp/client.key -subj "/CN=myuser" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl x509 -req -in /tmp/client.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/client.crt if [[ "$OSTYPE" == "darwin"* ]] then # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 @@ -63,7 +63,7 @@ fi rm client.csr # need to use pk8, otherwise I got this issue https://coderanch.com/t/706596/databases/Connection-string-ssl-client-certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl pkcs8 -topk8 -outform DER -in /tmp/client.key -out /tmp/client.key.pk8 -nocrypt +docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs8 -topk8 -outform DER -in /tmp/client.key -out /tmp/client.key.pk8 -nocrypt if [[ "$OSTYPE" == "darwin"* ]] then # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 diff --git a/connect/connect-debezium-postgresql-source/debezium-postgres-source-ssl.sh b/connect/connect-debezium-postgresql-source/debezium-postgres-source-ssl.sh index aefd656a52..888adf0249 100755 --- a/connect/connect-debezium-postgresql-source/debezium-postgres-source-ssl.sh +++ b/connect/connect-debezium-postgresql-source/debezium-postgres-source-ssl.sh @@ -30,11 +30,11 @@ rm -f ca.key #https://blog.crunchydata.com/blog/ssl-certificate-authentication-postgresql-docker-containers log "Creating a Root Certificate Authority (CA)" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -x509 -days 365 -nodes -out /tmp/ca.crt -keyout /tmp/ca.key -subj "/CN=root-ca" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -x509 -days 365 -nodes -out /tmp/ca.crt -keyout /tmp/ca.key -subj "/CN=root-ca" log "Generate the PostgreSQL server key and certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -nodes -out /tmp/server.csr -keyout /tmp/server.key -subj "/CN=postgres" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl x509 -req -in /tmp/server.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/server.crt +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -nodes -out /tmp/server.csr -keyout /tmp/server.key -subj "/CN=postgres" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl x509 -req -in /tmp/server.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/server.crt if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh index 4c4aa078b6..6a4cc87f99 100755 --- a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh +++ b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh @@ -28,7 +28,7 @@ rm -f mssql.key #https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-docker-container-security?view=sql-server-ver15 #https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-encrypted-connections?view=sql-server-ver15&preserve-view=true#client-initiated-encryption log "Create a self-signed certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sqlserver' -keyout /tmp/mssql.key -out /tmp/mssql.pem -days 365 +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sqlserver' -keyout /tmp/mssql.key -out /tmp/mssql.pem -days 365 if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/connect/connect-jdbc-mysql-sink/mysql-sink-mtls.sh b/connect/connect-jdbc-mysql-sink/mysql-sink-mtls.sh index 7ffa554e41..5122162aba 100755 --- a/connect/connect-jdbc-mysql-sink/mysql-sink-mtls.sh +++ b/connect/connect-jdbc-mysql-sink/mysql-sink-mtls.sh @@ -44,7 +44,7 @@ else fi docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword # Convert the client key and certificate files to a PKCS #12 archive -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 +docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 # Import the client key and certificate into a Java keystore: docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword cd - diff --git a/connect/connect-jdbc-mysql-sink/mysql-sink-ssl.sh b/connect/connect-jdbc-mysql-sink/mysql-sink-ssl.sh index d9374896a8..768445d245 100755 --- a/connect/connect-jdbc-mysql-sink/mysql-sink-ssl.sh +++ b/connect/connect-jdbc-mysql-sink/mysql-sink-ssl.sh @@ -44,7 +44,7 @@ else fi docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword # Convert the client key and certificate files to a PKCS #12 archive -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 +docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 # Import the client key and certificate into a Java keystore: docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword cd - diff --git a/connect/connect-jdbc-mysql-source/mysql-mtls.sh b/connect/connect-jdbc-mysql-source/mysql-mtls.sh index f668b550d9..e2536ddb19 100755 --- a/connect/connect-jdbc-mysql-source/mysql-mtls.sh +++ b/connect/connect-jdbc-mysql-source/mysql-mtls.sh @@ -44,7 +44,7 @@ else fi docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword # Convert the client key and certificate files to a PKCS #12 archive -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 +docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 # Import the client key and certificate into a Java keystore: docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword cd - diff --git a/connect/connect-jdbc-mysql-source/mysql-ssl.sh b/connect/connect-jdbc-mysql-source/mysql-ssl.sh index ae45e886a0..c1022a4b2f 100755 --- a/connect/connect-jdbc-mysql-source/mysql-ssl.sh +++ b/connect/connect-jdbc-mysql-source/mysql-ssl.sh @@ -43,7 +43,7 @@ else fi docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword # Convert the client key and certificate files to a PKCS #12 archive -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 +docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 # Import the client key and certificate into a Java keystore: docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword cd - diff --git a/connect/connect-jdbc-postgresql-sink/postgres-sink-mtls.sh b/connect/connect-jdbc-postgresql-sink/postgres-sink-mtls.sh index 7dee111a98..2ade861b5c 100755 --- a/connect/connect-jdbc-postgresql-sink/postgres-sink-mtls.sh +++ b/connect/connect-jdbc-postgresql-sink/postgres-sink-mtls.sh @@ -24,11 +24,11 @@ rm -f ca.key #https://blog.crunchydata.com/blog/ssl-certificate-authentication-postgresql-docker-containers log " Creating a Root Certificate Authority (CA)" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -x509 -days 365 -nodes -out /tmp/ca.crt -keyout /tmp/ca.key -subj "/CN=root-ca" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -x509 -days 365 -nodes -out /tmp/ca.crt -keyout /tmp/ca.key -subj "/CN=root-ca" log "Generate the PostgreSQL server key and certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -nodes -out /tmp/server.csr -keyout /tmp/server.key -subj "/CN=postgres" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl x509 -req -in /tmp/server.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/server.crt +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -nodes -out /tmp/server.csr -keyout /tmp/server.key -subj "/CN=postgres" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl x509 -req -in /tmp/server.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/server.crt if [[ "$OSTYPE" == "darwin"* ]] then # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 @@ -42,8 +42,8 @@ fi rm server.csr log "Generating the Client Key and Certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -nodes -out /tmp/client.csr -keyout /tmp/client.key -subj "/CN=myuser" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl x509 -req -in /tmp/client.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/client.crt +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -nodes -out /tmp/client.csr -keyout /tmp/client.key -subj "/CN=myuser" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl x509 -req -in /tmp/client.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/client.crt if [[ "$OSTYPE" == "darwin"* ]] then # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 @@ -57,7 +57,7 @@ fi rm client.csr # need to use pk8, otherwise I got this issue https://coderanch.com/t/706596/databases/Connection-string-ssl-client-certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl pkcs8 -topk8 -outform DER -in /tmp/client.key -out /tmp/client.key.pk8 -nocrypt +docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs8 -topk8 -outform DER -in /tmp/client.key -out /tmp/client.key.pk8 -nocrypt if [[ "$OSTYPE" == "darwin"* ]] then # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 diff --git a/connect/connect-jdbc-postgresql-sink/postgres-sink-ssl.sh b/connect/connect-jdbc-postgresql-sink/postgres-sink-ssl.sh index 84f7c1b520..b032f205a1 100755 --- a/connect/connect-jdbc-postgresql-sink/postgres-sink-ssl.sh +++ b/connect/connect-jdbc-postgresql-sink/postgres-sink-ssl.sh @@ -24,11 +24,11 @@ rm -f ca.key #https://blog.crunchydata.com/blog/ssl-certificate-authentication-postgresql-docker-containers log "Creating a Root Certificate Authority (CA)" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -x509 -days 365 -nodes -out /tmp/ca.crt -keyout /tmp/ca.key -subj "/CN=root-ca" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -x509 -days 365 -nodes -out /tmp/ca.crt -keyout /tmp/ca.key -subj "/CN=root-ca" log "Generate the PostgreSQL server key and certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -nodes -out /tmp/server.csr -keyout /tmp/server.key -subj "/CN=postgres" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl x509 -req -in /tmp/server.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/server.crt +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -nodes -out /tmp/server.csr -keyout /tmp/server.key -subj "/CN=postgres" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl x509 -req -in /tmp/server.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/server.crt if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/connect/connect-jdbc-postgresql-source/postgres-mtls.sh b/connect/connect-jdbc-postgresql-source/postgres-mtls.sh index 5d56522b31..387b6442ee 100755 --- a/connect/connect-jdbc-postgresql-source/postgres-mtls.sh +++ b/connect/connect-jdbc-postgresql-source/postgres-mtls.sh @@ -24,11 +24,11 @@ rm -f ca.key #https://blog.crunchydata.com/blog/ssl-certificate-authentication-postgresql-docker-containers log " Creating a Root Certificate Authority (CA)" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -x509 -days 365 -nodes -out /tmp/ca.crt -keyout /tmp/ca.key -subj "/CN=root-ca" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -x509 -days 365 -nodes -out /tmp/ca.crt -keyout /tmp/ca.key -subj "/CN=root-ca" log "Generate the PostgreSQL server key and certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -nodes -out /tmp/server.csr -keyout /tmp/server.key -subj "/CN=postgres" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl x509 -req -in /tmp/server.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/server.crt +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -nodes -out /tmp/server.csr -keyout /tmp/server.key -subj "/CN=postgres" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl x509 -req -in /tmp/server.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/server.crt if [[ "$OSTYPE" == "darwin"* ]] then # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 @@ -42,8 +42,8 @@ fi rm server.csr log "Generating the Client Key and Certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -nodes -out /tmp/client.csr -keyout /tmp/client.key -subj "/CN=myuser" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl x509 -req -in /tmp/client.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/client.crt +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -nodes -out /tmp/client.csr -keyout /tmp/client.key -subj "/CN=myuser" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl x509 -req -in /tmp/client.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/client.crt if [[ "$OSTYPE" == "darwin"* ]] then # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 @@ -57,7 +57,7 @@ fi rm client.csr # need to use pk8, otherwise I got this issue https://coderanch.com/t/706596/databases/Connection-string-ssl-client-certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl pkcs8 -topk8 -outform DER -in /tmp/client.key -out /tmp/client.key.pk8 -nocrypt +docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs8 -topk8 -outform DER -in /tmp/client.key -out /tmp/client.key.pk8 -nocrypt if [[ "$OSTYPE" == "darwin"* ]] then # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 diff --git a/connect/connect-jdbc-postgresql-source/postgres-ssl.sh b/connect/connect-jdbc-postgresql-source/postgres-ssl.sh index d25cac0a3f..542eba9bfc 100755 --- a/connect/connect-jdbc-postgresql-source/postgres-ssl.sh +++ b/connect/connect-jdbc-postgresql-source/postgres-ssl.sh @@ -24,11 +24,11 @@ rm -f ca.key #https://blog.crunchydata.com/blog/ssl-certificate-authentication-postgresql-docker-containers log "Creating a Root Certificate Authority (CA)" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -x509 -days 365 -nodes -out /tmp/ca.crt -keyout /tmp/ca.key -subj "/CN=root-ca" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -x509 -days 365 -nodes -out /tmp/ca.crt -keyout /tmp/ca.key -subj "/CN=root-ca" log "Generate the PostgreSQL server key and certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -nodes -out /tmp/server.csr -keyout /tmp/server.key -subj "/CN=postgres" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl x509 -req -in /tmp/server.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/server.crt +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -nodes -out /tmp/server.csr -keyout /tmp/server.key -subj "/CN=postgres" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl x509 -req -in /tmp/server.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/server.crt if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh b/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh index 3d03e3c1ca..e9512cb609 100755 --- a/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh +++ b/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh @@ -31,7 +31,7 @@ rm -f mssql.key #https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-docker-container-security?view=sql-server-ver15 #https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-encrypted-connections?view=sql-server-ver15&preserve-view=true#client-initiated-encryption log "Create a self-signed certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sqlserver' -keyout /tmp/mssql.key -out /tmp/mssql.pem -days 365 +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sqlserver' -keyout /tmp/mssql.key -out /tmp/mssql.pem -days 365 if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh b/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh index e1b5346f47..1a81e2bc75 100755 --- a/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh +++ b/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh @@ -32,7 +32,7 @@ rm -f mssql.key #https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-docker-container-security?view=sql-server-ver15 #https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-encrypted-connections?view=sql-server-ver15&preserve-view=true#client-initiated-encryption log "Create a self-signed certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sqlserver' -keyout /tmp/mssql.key -out /tmp/mssql.pem -days 365 +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sqlserver' -keyout /tmp/mssql.key -out /tmp/mssql.pem -days 365 if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh b/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh index c8fdd95ea8..fb1ad6269c 100755 --- a/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh +++ b/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh @@ -31,7 +31,7 @@ rm -f mssql.key #https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-docker-container-security?view=sql-server-ver15 #https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-encrypted-connections?view=sql-server-ver15&preserve-view=true#client-initiated-encryption log "Create a self-signed certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sqlserver' -keyout /tmp/mssql.key -out /tmp/mssql.pem -days 365 +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sqlserver' -keyout /tmp/mssql.key -out /tmp/mssql.pem -days 365 if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh b/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh index 531ea308f0..7a8e828c2e 100755 --- a/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh +++ b/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh @@ -32,7 +32,7 @@ rm -f mssql.key #https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-docker-container-security?view=sql-server-ver15 #https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-encrypted-connections?view=sql-server-ver15&preserve-view=true#client-initiated-encryption log "Create a self-signed certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sqlserver' -keyout /tmp/mssql.key -out /tmp/mssql.pem -days 365 +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sqlserver' -keyout /tmp/mssql.key -out /tmp/mssql.pem -days 365 if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/connect/connect-mongodb-sink/mongo-sink-ssl.sh b/connect/connect-mongodb-sink/mongo-sink-ssl.sh index 9be1865a76..7c06c8500d 100755 --- a/connect/connect-mongodb-sink/mongo-sink-ssl.sh +++ b/connect/connect-mongodb-sink/mongo-sink-ssl.sh @@ -22,7 +22,7 @@ rm -f mongo.crt rm -f mongo.key log "Create a self-signed certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=mongodb' -keyout /tmp/mongo.key -out /tmp/mongo.crt -days 365 +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=mongodb' -keyout /tmp/mongo.key -out /tmp/mongo.crt -days 365 if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/connect/connect-mongodb-source/mongo-source-ssl.sh b/connect/connect-mongodb-source/mongo-source-ssl.sh index cfc94fe872..9077c4f452 100755 --- a/connect/connect-mongodb-source/mongo-source-ssl.sh +++ b/connect/connect-mongodb-source/mongo-source-ssl.sh @@ -22,7 +22,7 @@ rm -f mongo.crt rm -f mongo.key log "Create a self-signed certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=mongodb' -keyout /tmp/mongo.key -out /tmp/mongo.crt -days 365 +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=mongodb' -keyout /tmp/mongo.key -out /tmp/mongo.crt -days 365 if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/environment/rbac-sasl-plain/start.sh b/environment/rbac-sasl-plain/start.sh index ca3969a522..96ae157bd7 100755 --- a/environment/rbac-sasl-plain/start.sh +++ b/environment/rbac-sasl-plain/start.sh @@ -41,10 +41,10 @@ else ls -lrt fi log "LDAPS: Creating a Root Certificate Authority (CA)" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -x509 -days 365 -nodes -out /tmp/ca.crt -keyout /tmp/ca.key -subj "/CN=root-ca" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -x509 -days 365 -nodes -out /tmp/ca.crt -keyout /tmp/ca.key -subj "/CN=root-ca" log "LDAPS: Generate the LDAPS server key and certificate" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl req -new -nodes -out /tmp/server.csr -keyout /tmp/server.key -subj "/CN=openldap" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} openssl x509 -req -in /tmp/server.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/server.crt +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -new -nodes -out /tmp/server.csr -keyout /tmp/server.key -subj "/CN=openldap" +docker run --quiet --rm -v $PWD:/tmp alpine/openssl x509 -req -in /tmp/server.csr -days 365 -CA /tmp/ca.crt -CAkey /tmp/ca.key -CAcreateserial -out /tmp/server.crt log "LDAPS: Create a JKS truststore" rm -f ldap_truststore.jks # We import the test CA certificate diff --git a/reproduction-models b/reproduction-models index f88628958b..d25236aacc 160000 --- a/reproduction-models +++ b/reproduction-models @@ -1 +1 @@ -Subproject commit f88628958bd26d4183ae976ff0cb64122d2028f4 +Subproject commit d25236aacc23f7f1196c77af6b995c2bfa715689 From 990ba85c1d179d4adec7aba0e9f29bd9f9ea9702 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 4 Dec 2024 14:43:04 +0100 Subject: [PATCH 078/659] use vulhub/openssl:1.0.1c image --- ccloud/confluent-for-kubernetes/start.sh | 4 ++-- ccloud/fm-snowflake-sink/fully-managed-snowflake-sink.sh | 4 ++-- connect/connect-jdbc-snowflake-sink/jdbc-snowflake-sink.sh | 4 ++-- .../connect-jdbc-snowflake-source/jdbc-snowflake-source.sh | 4 ++-- connect/connect-snowflake-sink/snowflake-sink-proxy.sh | 4 ++-- .../snowflake-sink-snowpipe-streaming.sh | 4 ++-- connect/connect-snowflake-sink/snowflake-sink.sh | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/ccloud/confluent-for-kubernetes/start.sh b/ccloud/confluent-for-kubernetes/start.sh index 4891c35865..ec05b9cae6 100755 --- a/ccloud/confluent-for-kubernetes/start.sh +++ b/ccloud/confluent-for-kubernetes/start.sh @@ -38,8 +38,8 @@ log "Install Confluent for Kubernetes" helm upgrade --install confluent-operator confluentinc/confluent-for-kubernetes log "Generate a CA pair" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "openssl genrsa -out /tmp/ca-key.pem 2048 && chown -R $(id -u $USER):$(id -g $USER) /tmp/" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "openssl req -new -key /tmp/ca-key.pem -x509 -days 1000 -out /tmp/ca.pem -subj '/C=US/ST=CA/L=MountainView/O=Confluent/OU=Operator/CN=TestCA' && chown -R $(id -u $USER):$(id -g $USER) /tmp/" +docker run -u0 --rm -v $PWD:/tmp vulhub/openssl:1.0.1c bash -c "openssl genrsa -out /tmp/ca-key.pem 2048 && chown -R $(id -u $USER):$(id -g $USER) /tmp/" +docker run -u0 --rm -v $PWD:/tmp vulhub/openssl:1.0.1c bash -c "openssl req -new -key /tmp/ca-key.pem -x509 -days 1000 -out /tmp/ca.pem -subj '/C=US/ST=CA/L=MountainView/O=Confluent/OU=Operator/CN=TestCA' && chown -R $(id -u $USER):$(id -g $USER) /tmp/" log "Create a Kuebernetes secret for inter-component TLS" kubectl create secret tls ca-pair-sslcerts \ diff --git a/ccloud/fm-snowflake-sink/fully-managed-snowflake-sink.sh b/ccloud/fm-snowflake-sink/fully-managed-snowflake-sink.sh index 8fd759c1ea..e311636b78 100755 --- a/ccloud/fm-snowflake-sink/fully-managed-snowflake-sink.sh +++ b/ccloud/fm-snowflake-sink/fully-managed-snowflake-sink.sh @@ -55,9 +55,9 @@ SNOWFLAKE_URL="https://$SNOWFLAKE_ACCOUNT_NAME.snowflakecomputing.com" cd ../../ccloud/fm-snowflake-sink # using v1 PBE-SHA1-RC4-128, see https://community.snowflake.com/s/article/Private-key-provided-is-invalid-or-not-supported-rsa-key-p8--data-isn-t-an-object-ID # Create encrypted Private key - keep this safe, do not share! -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -v1 PBE-SHA1-RC4-128 -out /tmp/snowflake_key.p8 -passout pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" +docker run -u0 --rm -v $PWD:/tmp vulhub/openssl:1.0.1c bash -c "openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -v1 PBE-SHA1-RC4-128 -out /tmp/snowflake_key.p8 -passout pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" # Generate public key from private key. You can share your public key. -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "openssl rsa -in /tmp/snowflake_key.p8 -pubout -out /tmp/snowflake_key.pub -passin pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" +docker run -u0 --rm -v $PWD:/tmp vulhub/openssl:1.0.1c bash -c "openssl rsa -in /tmp/snowflake_key.p8 -pubout -out /tmp/snowflake_key.pub -passin pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" RSA_PUBLIC_KEY=$(grep -v "BEGIN PUBLIC" snowflake_key.pub | grep -v "END PUBLIC"|tr -d '\n') RSA_PRIVATE_KEY=$(grep -v "BEGIN ENCRYPTED PRIVATE KEY" snowflake_key.p8 | grep -v "END ENCRYPTED PRIVATE KEY"|tr -d '\n') diff --git a/connect/connect-jdbc-snowflake-sink/jdbc-snowflake-sink.sh b/connect/connect-jdbc-snowflake-sink/jdbc-snowflake-sink.sh index 08588b97a7..c06e79c6d4 100755 --- a/connect/connect-jdbc-snowflake-sink/jdbc-snowflake-sink.sh +++ b/connect/connect-jdbc-snowflake-sink/jdbc-snowflake-sink.sh @@ -59,9 +59,9 @@ SNOWFLAKE_URL="https://$SNOWFLAKE_ACCOUNT_NAME.snowflakecomputing.com" cd ../../connect/connect-jdbc-snowflake-sink # using v1 PBE-SHA1-RC4-128, see https://community.snowflake.com/s/article/Private-key-provided-is-invalid-or-not-supported-rsa-key-p8--data-isn-t-an-object-ID # Create encrypted Private key - keep this safe, do not share! -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -v1 PBE-SHA1-RC4-128 -out /tmp/snowflake_key.p8 -passout pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" +docker run -u0 --rm -v $PWD:/tmp vulhub/openssl:1.0.1c bash -c "openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -v1 PBE-SHA1-RC4-128 -out /tmp/snowflake_key.p8 -passout pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" # Generate public key from private key. You can share your public key. -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "openssl rsa -in /tmp/snowflake_key.p8 -pubout -out /tmp/snowflake_key.pub -passin pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" +docker run -u0 --rm -v $PWD:/tmp vulhub/openssl:1.0.1c bash -c "openssl rsa -in /tmp/snowflake_key.p8 -pubout -out /tmp/snowflake_key.pub -passin pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" RSA_PUBLIC_KEY=$(grep -v "BEGIN PUBLIC" snowflake_key.pub | grep -v "END PUBLIC"|tr -d '\n') RSA_PRIVATE_KEY=$(grep -v "BEGIN ENCRYPTED PRIVATE KEY" snowflake_key.p8 | grep -v "END ENCRYPTED PRIVATE KEY"|tr -d '\n') diff --git a/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh b/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh index 457de05176..4b19ccc5dc 100755 --- a/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh +++ b/connect/connect-jdbc-snowflake-source/jdbc-snowflake-source.sh @@ -62,9 +62,9 @@ SNOWFLAKE_URL="https://$SNOWFLAKE_ACCOUNT_NAME.snowflakecomputing.com" cd ../../connect/connect-jdbc-snowflake-source # using v1 PBE-SHA1-RC4-128, see https://community.snowflake.com/s/article/Private-key-provided-is-invalid-or-not-supported-rsa-key-p8--data-isn-t-an-object-ID # Create encrypted Private key - keep this safe, do not share! -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -v1 PBE-SHA1-RC4-128 -out /tmp/snowflake_key.p8 -passout pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" +docker run -u0 --rm -v $PWD:/tmp vulhub/openssl:1.0.1c bash -c "openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -v1 PBE-SHA1-RC4-128 -out /tmp/snowflake_key.p8 -passout pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" # Generate public key from private key. You can share your public key. -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "openssl rsa -in /tmp/snowflake_key.p8 -pubout -out /tmp/snowflake_key.pub -passin pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" +docker run -u0 --rm -v $PWD:/tmp vulhub/openssl:1.0.1c bash -c "openssl rsa -in /tmp/snowflake_key.p8 -pubout -out /tmp/snowflake_key.pub -passin pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" if [ -z "$GITHUB_RUN_NUMBER" ] then diff --git a/connect/connect-snowflake-sink/snowflake-sink-proxy.sh b/connect/connect-snowflake-sink/snowflake-sink-proxy.sh index 63274bcff8..fc4e6b5f1b 100755 --- a/connect/connect-snowflake-sink/snowflake-sink-proxy.sh +++ b/connect/connect-snowflake-sink/snowflake-sink-proxy.sh @@ -49,9 +49,9 @@ SNOWFLAKE_URL="https://$SNOWFLAKE_ACCOUNT_NAME.snowflakecomputing.com" cd ../../connect/connect-snowflake-sink # using v1 PBE-SHA1-RC4-128, see https://community.snowflake.com/s/article/Private-key-provided-is-invalid-or-not-supported-rsa-key-p8--data-isn-t-an-object-ID # Create encrypted Private key - keep this safe, do not share! -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -v1 PBE-SHA1-RC4-128 -out /tmp/snowflake_key.p8 -passout pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" +docker run -u0 --rm -v $PWD:/tmp vulhub/openssl:1.0.1c bash -c "openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -v1 PBE-SHA1-RC4-128 -out /tmp/snowflake_key.p8 -passout pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" # Generate public key from private key. You can share your public key. -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "openssl rsa -in /tmp/snowflake_key.p8 -pubout -out /tmp/snowflake_key.pub -passin pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" +docker run -u0 --rm -v $PWD:/tmp vulhub/openssl:1.0.1c bash -c "openssl rsa -in /tmp/snowflake_key.p8 -pubout -out /tmp/snowflake_key.pub -passin pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" RSA_PUBLIC_KEY=$(grep -v "BEGIN PUBLIC" snowflake_key.pub | grep -v "END PUBLIC"|tr -d '\n') RSA_PRIVATE_KEY=$(grep -v "BEGIN ENCRYPTED PRIVATE KEY" snowflake_key.p8 | grep -v "END ENCRYPTED PRIVATE KEY"|tr -d '\n') diff --git a/connect/connect-snowflake-sink/snowflake-sink-snowpipe-streaming.sh b/connect/connect-snowflake-sink/snowflake-sink-snowpipe-streaming.sh index ede3455637..4276c76fb1 100755 --- a/connect/connect-snowflake-sink/snowflake-sink-snowpipe-streaming.sh +++ b/connect/connect-snowflake-sink/snowflake-sink-snowpipe-streaming.sh @@ -49,9 +49,9 @@ SNOWFLAKE_URL="https://$SNOWFLAKE_ACCOUNT_NAME.snowflakecomputing.com" cd ../../connect/connect-snowflake-sink # using v1 PBE-SHA1-RC4-128, see https://community.snowflake.com/s/article/Private-key-provided-is-invalid-or-not-supported-rsa-key-p8--data-isn-t-an-object-ID # Create encrypted Private key - keep this safe, do not share! -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -v1 PBE-SHA1-RC4-128 -out /tmp/snowflake_key.p8 -passout pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" +docker run -u0 --rm -v $PWD:/tmp vulhub/openssl:1.0.1c bash -c "openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -v1 PBE-SHA1-RC4-128 -out /tmp/snowflake_key.p8 -passout pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" # Generate public key from private key. You can share your public key. -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "openssl rsa -in /tmp/snowflake_key.p8 -pubout -out /tmp/snowflake_key.pub -passin pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" +docker run -u0 --rm -v $PWD:/tmp vulhub/openssl:1.0.1c bash -c "openssl rsa -in /tmp/snowflake_key.p8 -pubout -out /tmp/snowflake_key.pub -passin pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" RSA_PUBLIC_KEY=$(grep -v "BEGIN PUBLIC" snowflake_key.pub | grep -v "END PUBLIC"|tr -d '\n') RSA_PRIVATE_KEY=$(grep -v "BEGIN ENCRYPTED PRIVATE KEY" snowflake_key.p8 | grep -v "END ENCRYPTED PRIVATE KEY"|tr -d '\n') diff --git a/connect/connect-snowflake-sink/snowflake-sink.sh b/connect/connect-snowflake-sink/snowflake-sink.sh index c4ad521e83..4d43074e8c 100755 --- a/connect/connect-snowflake-sink/snowflake-sink.sh +++ b/connect/connect-snowflake-sink/snowflake-sink.sh @@ -49,9 +49,9 @@ SNOWFLAKE_URL="https://$SNOWFLAKE_ACCOUNT_NAME.snowflakecomputing.com" cd ../../connect/connect-snowflake-sink # using v1 PBE-SHA1-RC4-128, see https://community.snowflake.com/s/article/Private-key-provided-is-invalid-or-not-supported-rsa-key-p8--data-isn-t-an-object-ID # Create encrypted Private key - keep this safe, do not share! -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -v1 PBE-SHA1-RC4-128 -out /tmp/snowflake_key.p8 -passout pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" +docker run -u0 --rm -v $PWD:/tmp vulhub/openssl:1.0.1c bash -c "openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -v1 PBE-SHA1-RC4-128 -out /tmp/snowflake_key.p8 -passout pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" # Generate public key from private key. You can share your public key. -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "openssl rsa -in /tmp/snowflake_key.p8 -pubout -out /tmp/snowflake_key.pub -passin pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" +docker run -u0 --rm -v $PWD:/tmp vulhub/openssl:1.0.1c bash -c "openssl rsa -in /tmp/snowflake_key.p8 -pubout -out /tmp/snowflake_key.pub -passin pass:confluent && chown -R $(id -u $USER):$(id -g $USER) /tmp/" RSA_PUBLIC_KEY=$(grep -v "BEGIN PUBLIC" snowflake_key.pub | grep -v "END PUBLIC"|tr -d '\n') RSA_PRIVATE_KEY=$(grep -v "BEGIN ENCRYPTED PRIVATE KEY" snowflake_key.p8 | grep -v "END ENCRYPTED PRIVATE KEY"|tr -d '\n') From a07537c4f6e703b904079685d805b72613944026 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 5 Dec 2024 16:29:09 +0100 Subject: [PATCH 079/659] playground topic produce --tombstone improvements #6078 --- scripts/cli/playground | 164 ++++++++++++---------- scripts/cli/src/commands/topic/produce.sh | 154 ++++++++++---------- 2 files changed, 166 insertions(+), 152 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index ff2dd019aa..cdfe04c4fc 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8196,6 +8196,11 @@ function version_gt() { function set_kafka_client_tag() { + if [[ $TAG_BASE = 7.8.* ]] + then + export KAFKA_CLIENT_TAG="3.8.0" + fi + if [[ $TAG_BASE = 7.7.* ]] then export KAFKA_CLIENT_TAG="3.7.0" @@ -8699,7 +8704,7 @@ function get_ansible_version() { } function check_confluent_version() { - REQUIRED_CONFLUENT_VER=${1:-"3.0.0"} + REQUIRED_CONFLUENT_VER=${1:-"4.0.0"} CONFLUENT_VER=$(get_confluent_version) if version_gt $REQUIRED_CONFLUENT_VER $CONFLUENT_VER; then @@ -9785,7 +9790,7 @@ function maybe_delete_ccloud_environment () { # log "🧹❌ Confluent Cloud cluster will be deleted..." verify_installed "confluent" - check_confluent_version 2.0.0 || exit 1 + check_confluent_version 4.0.0 || exit 1 verify_confluent_login "confluent kafka cluster list" export QUIET=true @@ -20552,32 +20557,6 @@ playground_topic_produce_command() { then key=$forced_key fi - log "🧟 Sending tombstone for key $key in topic $topic" - if [[ "$environment" == "ccloud" ]] - then - get_connect_image - - if [[ -n "$verbose" ]] - then - log "🐞 CLI command used to produce data" - echo "echo \"$key|NULL\" | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security --property parse.key=true --property key.separator=\"|\" --property null.marker=NULL" - fi - echo "$key|NULL" | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security --property parse.key=true --property key.separator="|" --property null.marker=NULL - else - if [[ -n "$verbose" ]] - then - log "🐞 CLI command used to produce data" - echo "echo \"$key|NULL\" | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security --property parse.key=true --property key.separator=\"|\" --property null.marker=NULL" - fi - echo "$key|NULL" | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security --property parse.key=true --property key.separator="|" --property null.marker=NULL - fi - - if [[ -n "$consume" ]] - then - playground topic consume --topic $topic - fi - # nothing else to do - exit 0 fi if [[ -n "$headers" ]] @@ -20724,8 +20703,11 @@ playground_topic_produce_command() { key_schema_type=$schema_type fi - identify_schema "$value_schema_file" "value" - value_schema_type=$schema_type + if [[ ! -n "$tombstone" ]] + then + identify_schema "$value_schema_file" "value" + value_schema_type=$schema_type + fi if [[ -n "$key" ]] then @@ -20979,10 +20961,14 @@ playground_topic_produce_command() { log "✨ generating key data..." generate_data "$key_schema_type" "$key_schema_file" "$output_key_file" "KEY" fi - log "✨ generating value data..." - generate_data "$value_schema_type" "$value_schema_file" "$output_value_file" "VALUE" - - nb_generated_messages=$(wc -l < $output_value_file) + if [[ ! -n "$tombstone" ]] + then + log "✨ generating value data..." + generate_data "$value_schema_type" "$value_schema_file" "$output_value_file" "VALUE" + nb_generated_messages=$(wc -l < $output_value_file) + else + nb_generated_messages=$(wc -l < $output_key_file) + fi nb_generated_messages=${nb_generated_messages// /} if [ "$nb_generated_messages" == "0" ] @@ -21021,8 +21007,18 @@ playground_topic_produce_command() { if [[ -n "$key" ]] then - # merging key and value files - paste -d "|" $output_key_file $output_value_file > $output_final_file + if [[ ! -n "$tombstone" ]] + then + # merging key and value files + paste -d "|" $output_key_file $output_value_file > $output_final_file + else + touch "$output_value_file" + while read -r line; do + echo "NULL" >> "$output_value_file" + done < "$output_key_file" + # merging key and value files + paste -d "|" $output_key_file $output_value_file > $output_final_file + fi else cp $output_value_file $output_final_file fi @@ -21314,6 +21310,12 @@ playground_topic_produce_command() { compression="--compression-codec $compression_codec" fi + if [[ -n "$tombstone" ]] + then + log "🧟 Sending tombstone(s)" + tombstone="--property null.marker=NULL" + fi + function handle_signal { echo "Stopping..." stop=1 @@ -21358,7 +21360,15 @@ playground_topic_produce_command() { then head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' > /tmp/verbose_input_file.txt fi - case "${value_schema_type}" in + + switch_schema_type="" + if [[ -n "$tombstone" ]] + then + switch_schema_type="${key_schema_type}" + else + switch_schema_type="${value_schema_type}" + fi + case "${switch_schema_type}" in json|sql|raw) if [[ "$environment" == "ccloud" ]] then @@ -21370,17 +21380,17 @@ playground_topic_produce_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression --property parse.key=true --property key.separator=\"|\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression --property parse.key=true --property key.separator="|" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression --property parse.key=true --property key.separator=\"|\" " + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\" " fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression --property parse.key=true --property key.separator="|" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" fi else @@ -21390,17 +21400,17 @@ playground_topic_produce_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone fi fi else @@ -21411,16 +21421,16 @@ playground_topic_produce_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression --property parse.key=true --property key.separator=\"|\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" + echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression --property parse.key=true --property key.separator="|" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" else if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression --property parse.key=true --property key.separator=\"|\"" + echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\"" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression --property parse.key=true --property key.separator="|" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" fi else if [[ -n "$headers" ]] @@ -21428,16 +21438,16 @@ playground_topic_produce_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" + echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" else if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone fi fi fi @@ -21488,17 +21498,17 @@ playground_topic_produce_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi else if [ "$key_schema_type" = "avro" ] || [ "$key_schema_type" = "protobuf" ] || [ "$key_schema_type" = "json-schema" ] @@ -21507,18 +21517,18 @@ playground_topic_produce_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi fi else @@ -21528,17 +21538,17 @@ playground_topic_produce_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi fi else @@ -21560,18 +21570,18 @@ playground_topic_produce_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$key_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$key_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi else docker cp $root_folder/scripts/cli/src/tools-log4j.properties $container:/tmp/tools-log4j.properties > /dev/null 2>&1 @@ -21580,16 +21590,16 @@ playground_topic_produce_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$key_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$key_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi fi else @@ -21599,16 +21609,16 @@ playground_topic_produce_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$key_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=/tmp/value_schema_file $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi fi fi diff --git a/scripts/cli/src/commands/topic/produce.sh b/scripts/cli/src/commands/topic/produce.sh index 662ebb3bef..7550d88515 100644 --- a/scripts/cli/src/commands/topic/produce.sh +++ b/scripts/cli/src/commands/topic/produce.sh @@ -148,32 +148,6 @@ then then key=$forced_key fi - log "🧟 Sending tombstone for key $key in topic $topic" - if [[ "$environment" == "ccloud" ]] - then - get_connect_image - - if [[ -n "$verbose" ]] - then - log "🐞 CLI command used to produce data" - echo "echo \"$key|NULL\" | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security --property parse.key=true --property key.separator=\"|\" --property null.marker=NULL" - fi - echo "$key|NULL" | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security --property parse.key=true --property key.separator="|" --property null.marker=NULL - else - if [[ -n "$verbose" ]] - then - log "🐞 CLI command used to produce data" - echo "echo \"$key|NULL\" | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security --property parse.key=true --property key.separator=\"|\" --property null.marker=NULL" - fi - echo "$key|NULL" | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security --property parse.key=true --property key.separator="|" --property null.marker=NULL - fi - - if [[ -n "$consume" ]] - then - playground topic consume --topic $topic - fi - # nothing else to do - exit 0 fi if [[ -n "$headers" ]] @@ -320,8 +294,11 @@ then key_schema_type=$schema_type fi -identify_schema "$value_schema_file" "value" -value_schema_type=$schema_type +if [[ ! -n "$tombstone" ]] +then + identify_schema "$value_schema_file" "value" + value_schema_type=$schema_type +fi if [[ -n "$key" ]] then @@ -571,10 +548,14 @@ then log "✨ generating key data..." generate_data "$key_schema_type" "$key_schema_file" "$output_key_file" "KEY" fi -log "✨ generating value data..." -generate_data "$value_schema_type" "$value_schema_file" "$output_value_file" "VALUE" - -nb_generated_messages=$(wc -l < $output_value_file) +if [[ ! -n "$tombstone" ]] +then + log "✨ generating value data..." + generate_data "$value_schema_type" "$value_schema_file" "$output_value_file" "VALUE" + nb_generated_messages=$(wc -l < $output_value_file) +else + nb_generated_messages=$(wc -l < $output_key_file) +fi nb_generated_messages=${nb_generated_messages// /} if [ "$nb_generated_messages" == "0" ] @@ -613,8 +594,18 @@ fi if [[ -n "$key" ]] then - # merging key and value files - paste -d "|" $output_key_file $output_value_file > $output_final_file + if [[ ! -n "$tombstone" ]] + then + # merging key and value files + paste -d "|" $output_key_file $output_value_file > $output_final_file + else + touch "$output_value_file" + while read -r line; do + echo "NULL" >> "$output_value_file" + done < "$output_key_file" + # merging key and value files + paste -d "|" $output_key_file $output_value_file > $output_final_file + fi else cp $output_value_file $output_final_file fi @@ -903,6 +894,11 @@ then compression="--compression-codec $compression_codec" fi +if [[ -n "$tombstone" ]] +then + log "🧟 Sending tombstone(s)" + tombstone="--property null.marker=NULL" +fi function handle_signal { echo "Stopping..." @@ -948,7 +944,15 @@ do then head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' > /tmp/verbose_input_file.txt fi - case "${value_schema_type}" in + + switch_schema_type="" + if [[ -n "$tombstone" ]] + then + switch_schema_type="${key_schema_type}" + else + switch_schema_type="${value_schema_type}" + fi + case "${switch_schema_type}" in json|sql|raw) if [[ "$environment" == "ccloud" ]] then @@ -960,17 +964,17 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression --property parse.key=true --property key.separator=\"|\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression --property parse.key=true --property key.separator="|" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression --property parse.key=true --property key.separator=\"|\" " + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\" " fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression --property parse.key=true --property key.separator="|" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" fi else if [[ -n "$headers" ]] @@ -979,17 +983,17 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone fi fi else @@ -1000,16 +1004,16 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression --property parse.key=true --property key.separator=\"|\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" + echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression --property parse.key=true --property key.separator="|" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" else if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression --property parse.key=true --property key.separator=\"|\"" + echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\"" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression --property parse.key=true --property key.separator="|" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" fi else if [[ -n "$headers" ]] @@ -1017,16 +1021,16 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" + echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" else if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -i $container kafka-console-producer --broker-list $bootstrap_server --topic $topic $security $producer_properties $compression $tombstone fi fi fi @@ -1077,17 +1081,17 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi else if [ "$key_schema_type" = "avro" ] || [ "$key_schema_type" = "protobuf" ] || [ "$key_schema_type" = "json-schema" ] @@ -1096,17 +1100,17 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi fi else @@ -1116,17 +1120,17 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi fi else @@ -1148,18 +1152,18 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$key_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$key_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi else docker cp $root_folder/scripts/cli/src/tools-log4j.properties $container:/tmp/tools-log4j.properties > /dev/null 2>&1 @@ -1168,16 +1172,16 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$key_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$key_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi fi else @@ -1187,16 +1191,16 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$key_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=\"/tmp/value_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression" + echo "cat /tmp/verbose_input_file.txt | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file=/tmp/value_schema_file $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -i $container kafka-$value_schema_type-console-producer --broker-list $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic $security --property value.schema.file="/tmp/value_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi fi fi From 5c491d518b2259f4ae39a3c493414c7220ac8378 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Dec 2024 10:28:35 +0100 Subject: [PATCH 080/659] update --- scripts/cli/tag-list.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/cli/tag-list.txt b/scripts/cli/tag-list.txt index a87f9d6be5..f01095e5a3 100644 --- a/scripts/cli/tag-list.txt +++ b/scripts/cli/tag-list.txt @@ -55,6 +55,7 @@ 6.0.0 6.0.1 6.0.10 +6.0.11 6.0.12 6.0.13 6.0.14 @@ -63,6 +64,7 @@ 6.0.3 6.0.4 6.0.5 +6.0.6 6.0.7 6.0.8 6.0.9 @@ -79,11 +81,13 @@ 6.1.4 6.1.5 6.1.6 +6.1.7 6.1.8 6.1.9 6.2.0 6.2.1 6.2.10 +6.2.11 6.2.12 6.2.13 6.2.14 From bd62c1be6af84736d63ed5a3b9bfb60673b6f634 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Dec 2024 13:29:51 +0100 Subject: [PATCH 081/659] added playground tools certs-create --- .../fully-managed-mqtt-source-mtls.sh | 7 +- .../fm-mqtt-source/security/certs-create.sh | 80 ------------------ .../fully-managed-rabbitmq-sink-ssl.sh | 8 +- .../fm-rabbitmq-sink/security/certs-create.sh | 80 ------------------ .../fully-managed-rabbitmq-source-ssl.sh | 9 +-- .../security/certs-clean.sh | 9 --- .../security/certs-create.sh | 81 ------------------- .../security/certs-verify.sh | 14 ---- ccloud/rest-proxy-security-plugin/start.sh | 7 +- 9 files changed, 12 insertions(+), 283 deletions(-) delete mode 100755 ccloud/fm-mqtt-source/security/certs-create.sh delete mode 100755 ccloud/fm-rabbitmq-sink/security/certs-create.sh delete mode 100755 ccloud/rest-proxy-security-plugin/security/certs-clean.sh delete mode 100755 ccloud/rest-proxy-security-plugin/security/certs-create.sh delete mode 100755 ccloud/rest-proxy-security-plugin/security/certs-verify.sh diff --git a/ccloud/fm-mqtt-source/fully-managed-mqtt-source-mtls.sh b/ccloud/fm-mqtt-source/fully-managed-mqtt-source-mtls.sh index ca8a15ee4b..78c5634d50 100755 --- a/ccloud/fm-mqtt-source/fully-managed-mqtt-source-mtls.sh +++ b/ccloud/fm-mqtt-source/fully-managed-mqtt-source-mtls.sh @@ -4,12 +4,11 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -cd ${DIR}/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/ && chmod a+r /tmp/*" +cd ../../ccloud/fm-mqtt-source/security +playground tools certs-create --output-folder "$PWD" --container connect --container mosquitto --verbose base64_truststore=$(cat $PWD/kafka.connect.truststore.jks | base64 | tr -d '\n') base64_keystore=$(cat $PWD/kafka.connect.keystore.jks | base64 | tr -d '\n') -cd ${DIR} +cd - NGROK_AUTH_TOKEN=${NGROK_AUTH_TOKEN:-$1} diff --git a/ccloud/fm-mqtt-source/security/certs-create.sh b/ccloud/fm-mqtt-source/security/certs-create.sh deleted file mode 100755 index d047f00729..0000000000 --- a/ccloud/fm-mqtt-source/security/certs-create.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in connect mosquitto -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > ${i}_sslkey_creds - echo "confluent" > ${i}_keystore_creds - echo "confluent" > ${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent - - - cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" - keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent - -done diff --git a/ccloud/fm-rabbitmq-sink/fully-managed-rabbitmq-sink-ssl.sh b/ccloud/fm-rabbitmq-sink/fully-managed-rabbitmq-sink-ssl.sh index b31987e333..6f20bf3b80 100755 --- a/ccloud/fm-rabbitmq-sink/fully-managed-rabbitmq-sink-ssl.sh +++ b/ccloud/fm-rabbitmq-sink/fully-managed-rabbitmq-sink-ssl.sh @@ -6,8 +6,9 @@ source ${DIR}/../../scripts/utils.sh NGROK_AUTH_TOKEN=${NGROK_AUTH_TOKEN:-$1} cd ../../ccloud/fm-rabbitmq-sink/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/ && chmod a+r /tmp/*" +playground tools certs-create --output-folder "$PWD" --container connect --container rabbitmq +base64_truststore=$(cat $PWD/kafka.connect.truststore.jks | base64 | tr -d '\n') +base64_keystore=$(cat $PWD/kafka.connect.keystore.jks | base64 | tr -d '\n') cd - display_ngrok_warning @@ -72,9 +73,6 @@ set +e playground connector delete --connector $connector_name > /dev/null 2>&1 set -e -base64_truststore=$(cat $PWD/security/kafka.connect.truststore.jks | base64 | tr -d '\n') -base64_keystore=$(cat $PWD/security/kafka.connect.keystore.jks | base64 | tr -d '\n') - log "Creating fully managed connector" playground connector create-or-update --connector $connector_name << EOF { diff --git a/ccloud/fm-rabbitmq-sink/security/certs-create.sh b/ccloud/fm-rabbitmq-sink/security/certs-create.sh deleted file mode 100755 index b89a52764d..0000000000 --- a/ccloud/fm-rabbitmq-sink/security/certs-create.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in connect rabbitmq -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > ${i}_sslkey_creds - echo "confluent" > ${i}_keystore_creds - echo "confluent" > ${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent - - - # cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" - # keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent - -done diff --git a/ccloud/fm-rabbitmq-source/fully-managed-rabbitmq-source-ssl.sh b/ccloud/fm-rabbitmq-source/fully-managed-rabbitmq-source-ssl.sh index 3999ea307b..6c22fd6f8f 100755 --- a/ccloud/fm-rabbitmq-source/fully-managed-rabbitmq-source-ssl.sh +++ b/ccloud/fm-rabbitmq-source/fully-managed-rabbitmq-source-ssl.sh @@ -4,10 +4,10 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh - cd ../../ccloud/fm-rabbitmq-source/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/ && chmod a+r /tmp/*" +playground tools certs-create --output-folder "$PWD" --container connect --container rabbitmq +base64_truststore=$(cat $PWD/kafka.connect.truststore.jks | base64 | tr -d '\n') +base64_keystore=$(cat $PWD/kafka.connect.keystore.jks | base64 | tr -d '\n') cd - NGROK_AUTH_TOKEN=${NGROK_AUTH_TOKEN:-$1} @@ -61,9 +61,6 @@ sleep 6 log "Send message to RabbitMQ in myqueue" docker exec rabbitmq_producer bash -c "python /producer.py myqueue 5" -base64_truststore=$(cat $PWD/security/kafka.connect.truststore.jks | base64 | tr -d '\n') -base64_keystore=$(cat $PWD/security/kafka.connect.keystore.jks | base64 | tr -d '\n') - log "Creating fully managed connector" playground connector create-or-update --connector $connector_name << EOF { diff --git a/ccloud/rest-proxy-security-plugin/security/certs-clean.sh b/ccloud/rest-proxy-security-plugin/security/certs-clean.sh deleted file mode 100755 index 91fa79b003..0000000000 --- a/ccloud/rest-proxy-security-plugin/security/certs-clean.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -set -o nounset \ - -o errexit \ - -o verbose -# -o xtrace - -# Cleanup files -rm -f *.crt *.csr *_creds *.jks *.srl *.key *.pem *.der *.p12 extfile diff --git a/ccloud/rest-proxy-security-plugin/security/certs-create.sh b/ccloud/rest-proxy-security-plugin/security/certs-create.sh deleted file mode 100755 index 05ba4ba434..0000000000 --- a/ccloud/rest-proxy-security-plugin/security/certs-create.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_KEY=$1 - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in restproxy $CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_KEY -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > /tmp/${i}_sslkey_creds - echo "confluent" > /tmp/${i}_keystore_creds - echo "confluent" > /tmp/${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent - - - cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" - keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent -done diff --git a/ccloud/rest-proxy-security-plugin/security/certs-verify.sh b/ccloud/rest-proxy-security-plugin/security/certs-verify.sh deleted file mode 100755 index 038a275faf..0000000000 --- a/ccloud/rest-proxy-security-plugin/security/certs-verify.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -set -o nounset \ - -o errexit \ - -o verbose - -# See what is in each keystore and truststore -for i in restproxy $CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_KEY -do - echo "------------------------------- $i keystore -------------------------------" - keytool -list -v -keystore /tmp/kafka.$i.keystore.jks -storepass confluent | grep -e Alias -e Entry - echo "------------------------------- $i truststore -------------------------------" - keytool -list -v -keystore /tmp/kafka.$i.truststore.jks -storepass confluent | grep -e Alias -e Entry -done diff --git a/ccloud/rest-proxy-security-plugin/start.sh b/ccloud/rest-proxy-security-plugin/start.sh index ab2101c1ef..39cb43efe8 100755 --- a/ccloud/rest-proxy-security-plugin/start.sh +++ b/ccloud/rest-proxy-security-plugin/start.sh @@ -32,10 +32,9 @@ sed -e "s|:CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_KEY:|$CCLOUD_REST_PROXY_SECURIT -e "s|:CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_SECRET:|$CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_SECRET|g" \ ../../ccloud/rest-proxy-security-plugin/kafka-rest.jaas-template.conf > ../../ccloud/rest-proxy-security-plugin/kafka-rest.jaas.conf -cd ${DIR}/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 $CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_KEY && chown -R $(id -u $USER):$(id -g $USER) /tmp/" -cd ${DIR} +cd ../../ccloud/rest-proxy-security-plugin/security +playground tools certs-create --output-folder "$PWD" --container restproxy --container $CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_KEY --verbose +cd - docker compose -f "${PWD}/docker-compose.yml" up -d --quiet-pull From e1a05d30d6bf9594f487a5519c007c11751180ad Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Dec 2024 13:30:15 +0100 Subject: [PATCH 082/659] added playground tools certs-create --- .../active-mq-sink-mtls.sh | 7 +- .../security/certs-create.sh | 68 -- .../security/certs-create.sh | 68 -- .../connect-ibm-mq-sink/ibm-mq-sink-mtls.sh | 7 +- .../connect-ibm-mq-sink/ibm-mq-sink-ssl.sh | 7 +- .../security/certs-create.sh | 80 -- connect/connect-ibm-mq-source/ibm-mq-mtls.sh | 7 +- connect/connect-ibm-mq-source/ibm-mq-ssl.sh | 7 +- .../security/certs-create.sh | 80 -- connect/connect-mqtt-sink/mqtt-sink-mtls.sh | 7 +- .../security/certs-create.sh | 80 -- .../connect-mqtt-source/mqtt-source-mtls.sh | 7 +- .../security/certs-create.sh | 80 -- .../rabbitmq-sink-ssl.sh | 3 +- .../security/certs-create.sh | 80 -- .../rabbitmq-source-ssl.sh | 3 +- .../security/certs-create.sh | 80 -- .../docker-compose.plaintext.yml | 2 +- .../connect-splunk-source/splunk-source.sh | 40 +- environment/2way-ssl/start.sh | 6 +- environment/sasl-ssl/security/certs-create.sh | 10 +- environment/sasl-ssl/start.sh | 6 +- environment/ssl_kerberos/start.sh | 8 +- .../start-ldaps.sh | 6 +- reproduction-models | 2 +- scripts/cli/completions.bash | 862 +++++++++--------- scripts/cli/playground | 183 ++++ scripts/cli/playground.json | 43 + scripts/cli/playground.yaml | 32 + scripts/cli/src/bashly.yml | 35 + .../cli/src/commands/tools/certs-create.sh | 28 + scripts/cli/src/openssl.cnf | 392 ++++++++ scripts/cli/src/ssl/certs-create.sh | 95 ++ 33 files changed, 1291 insertions(+), 1130 deletions(-) delete mode 100755 connect/connect-active-mq-sink/security/certs-create.sh delete mode 100755 connect/connect-active-mq-source/security/certs-create.sh delete mode 100755 connect/connect-ibm-mq-sink/security/certs-create.sh delete mode 100755 connect/connect-ibm-mq-source/security/certs-create.sh delete mode 100755 connect/connect-mqtt-sink/security/certs-create.sh delete mode 100755 connect/connect-mqtt-source/security/certs-create.sh delete mode 100755 connect/connect-rabbitmq-sink/security/certs-create.sh delete mode 100755 connect/connect-rabbitmq-source/security/certs-create.sh create mode 100644 scripts/cli/src/commands/tools/certs-create.sh create mode 100644 scripts/cli/src/openssl.cnf create mode 100755 scripts/cli/src/ssl/certs-create.sh diff --git a/connect/connect-active-mq-sink/active-mq-sink-mtls.sh b/connect/connect-active-mq-sink/active-mq-sink-mtls.sh index b7f927a5ac..cf9a414df1 100755 --- a/connect/connect-active-mq-sink/active-mq-sink-mtls.sh +++ b/connect/connect-active-mq-sink/active-mq-sink-mtls.sh @@ -4,10 +4,9 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -cd ${DIR}/security -log "🔐 Generate keys and certificates used for SSL using rmohr/activemq:5.15.9 image" -docker run -u0 --rm -v $PWD:/tmp rmohr/activemq:5.15.9 bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/" -cd ${DIR} +cd ../../connect/connect-active-mq-sink/security +playground tools certs-create --output-folder "$PWD" --container connect --container activemq +cd - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.mtls.yml" diff --git a/connect/connect-active-mq-sink/security/certs-create.sh b/connect/connect-active-mq-sink/security/certs-create.sh deleted file mode 100755 index bc2f48cabd..0000000000 --- a/connect/connect-active-mq-sink/security/certs-create.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in connect activemq -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > /tmp/${i}_sslkey_creds - echo "confluent" > /tmp/${i}_keystore_creds - echo "confluent" > /tmp/${i}_truststore_creds - - keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore "/usr/local/openjdk-8/lib/security/cacerts" -srcstorepass changeit -deststorepass confluent -done diff --git a/connect/connect-active-mq-source/security/certs-create.sh b/connect/connect-active-mq-source/security/certs-create.sh deleted file mode 100755 index bc2f48cabd..0000000000 --- a/connect/connect-active-mq-source/security/certs-create.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in connect activemq -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > /tmp/${i}_sslkey_creds - echo "confluent" > /tmp/${i}_keystore_creds - echo "confluent" > /tmp/${i}_truststore_creds - - keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore "/usr/local/openjdk-8/lib/security/cacerts" -srcstorepass changeit -deststorepass confluent -done diff --git a/connect/connect-ibm-mq-sink/ibm-mq-sink-mtls.sh b/connect/connect-ibm-mq-sink/ibm-mq-sink-mtls.sh index 5de5fc8b0a..7402443c3a 100755 --- a/connect/connect-ibm-mq-sink/ibm-mq-sink-mtls.sh +++ b/connect/connect-ibm-mq-sink/ibm-mq-sink-mtls.sh @@ -31,10 +31,9 @@ then fi cd - -cd ${DIR}/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/ && chmod a+r /tmp/*" -cd ${DIR} +cd ../../connect/connect-ibm-mq-sink/security +playground tools certs-create --output-folder "$PWD" --container connect --container ibmmq +cd - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.mtls.yml" diff --git a/connect/connect-ibm-mq-sink/ibm-mq-sink-ssl.sh b/connect/connect-ibm-mq-sink/ibm-mq-sink-ssl.sh index 7ce278ff8e..c04379eefb 100755 --- a/connect/connect-ibm-mq-sink/ibm-mq-sink-ssl.sh +++ b/connect/connect-ibm-mq-sink/ibm-mq-sink-ssl.sh @@ -31,10 +31,9 @@ then fi cd - -cd ${DIR}/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/ && chmod a+r /tmp/*" -cd ${DIR} +cd ../../connect/connect-ibm-mq-sink/security +playground tools certs-create --output-folder "$PWD" --container connect --container ibmmq +cd - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.ssl.yml" diff --git a/connect/connect-ibm-mq-sink/security/certs-create.sh b/connect/connect-ibm-mq-sink/security/certs-create.sh deleted file mode 100755 index e9e0733a3b..0000000000 --- a/connect/connect-ibm-mq-sink/security/certs-create.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in connect ibmmq -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > ${i}_sslkey_creds - echo "confluent" > ${i}_keystore_creds - echo "confluent" > ${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent - - - cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" - keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent - -done diff --git a/connect/connect-ibm-mq-source/ibm-mq-mtls.sh b/connect/connect-ibm-mq-source/ibm-mq-mtls.sh index 86868e6394..cd58f50756 100755 --- a/connect/connect-ibm-mq-source/ibm-mq-mtls.sh +++ b/connect/connect-ibm-mq-source/ibm-mq-mtls.sh @@ -31,10 +31,9 @@ then fi cd - -cd ${DIR}/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/ && chmod a+r /tmp/*" -cd ${DIR} +cd ../../connect/connect-ibm-mq-source/security +playground tools certs-create --output-folder "$PWD" --container connect --container ibmmq +cd - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.mtls.yml" diff --git a/connect/connect-ibm-mq-source/ibm-mq-ssl.sh b/connect/connect-ibm-mq-source/ibm-mq-ssl.sh index d49c8518ae..aea02b60ab 100755 --- a/connect/connect-ibm-mq-source/ibm-mq-ssl.sh +++ b/connect/connect-ibm-mq-source/ibm-mq-ssl.sh @@ -31,10 +31,9 @@ then fi cd - -cd ${DIR}/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/ && chmod a+r /tmp/*" -cd ${DIR} +cd ../../connect/connect-ibm-mq-source/security +playground tools certs-create --output-folder "$PWD" --container connect --container ibmmq +cd - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.ssl.yml" diff --git a/connect/connect-ibm-mq-source/security/certs-create.sh b/connect/connect-ibm-mq-source/security/certs-create.sh deleted file mode 100755 index e9e0733a3b..0000000000 --- a/connect/connect-ibm-mq-source/security/certs-create.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in connect ibmmq -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > ${i}_sslkey_creds - echo "confluent" > ${i}_keystore_creds - echo "confluent" > ${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent - - - cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" - keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent - -done diff --git a/connect/connect-mqtt-sink/mqtt-sink-mtls.sh b/connect/connect-mqtt-sink/mqtt-sink-mtls.sh index 33e5e61265..6efa9a6459 100755 --- a/connect/connect-mqtt-sink/mqtt-sink-mtls.sh +++ b/connect/connect-mqtt-sink/mqtt-sink-mtls.sh @@ -4,10 +4,9 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -cd ${DIR}/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/ && chmod a+r /tmp/*" -cd ${DIR} +cd ../../connect/connect-mqtt-sink/security +playground tools certs-create --output-folder "$PWD" --container connect --container mosquitto +cd - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.mtls.yml" diff --git a/connect/connect-mqtt-sink/security/certs-create.sh b/connect/connect-mqtt-sink/security/certs-create.sh deleted file mode 100755 index d047f00729..0000000000 --- a/connect/connect-mqtt-sink/security/certs-create.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in connect mosquitto -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > ${i}_sslkey_creds - echo "confluent" > ${i}_keystore_creds - echo "confluent" > ${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent - - - cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" - keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent - -done diff --git a/connect/connect-mqtt-source/mqtt-source-mtls.sh b/connect/connect-mqtt-source/mqtt-source-mtls.sh index cc360fb1a5..8b8c114ffc 100755 --- a/connect/connect-mqtt-source/mqtt-source-mtls.sh +++ b/connect/connect-mqtt-source/mqtt-source-mtls.sh @@ -5,10 +5,9 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -cd ${DIR}/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/ && chmod a+r /tmp/*" -cd ${DIR} +cd ../../connect/connect-mqtt-source/security +playground tools certs-create --output-folder "$PWD" --container connect --container mosquitto +cd - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.mtls.yml" diff --git a/connect/connect-mqtt-source/security/certs-create.sh b/connect/connect-mqtt-source/security/certs-create.sh deleted file mode 100755 index d047f00729..0000000000 --- a/connect/connect-mqtt-source/security/certs-create.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in connect mosquitto -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > ${i}_sslkey_creds - echo "confluent" > ${i}_keystore_creds - echo "confluent" > ${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent - - - cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" - keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent - -done diff --git a/connect/connect-rabbitmq-sink/rabbitmq-sink-ssl.sh b/connect/connect-rabbitmq-sink/rabbitmq-sink-ssl.sh index c46bc74e58..05f9fff08b 100755 --- a/connect/connect-rabbitmq-sink/rabbitmq-sink-ssl.sh +++ b/connect/connect-rabbitmq-sink/rabbitmq-sink-ssl.sh @@ -5,8 +5,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh cd ../../connect/connect-rabbitmq-sink/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/ && chmod a+r /tmp/*" +playground tools certs-create --output-folder "$PWD" --container connect --container rabbitmq cd - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} diff --git a/connect/connect-rabbitmq-sink/security/certs-create.sh b/connect/connect-rabbitmq-sink/security/certs-create.sh deleted file mode 100755 index 04573a38ef..0000000000 --- a/connect/connect-rabbitmq-sink/security/certs-create.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in connect rabbitmq -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > ${i}_sslkey_creds - echo "confluent" > ${i}_keystore_creds - echo "confluent" > ${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent - - - cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" - keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent - -done diff --git a/connect/connect-rabbitmq-source/rabbitmq-source-ssl.sh b/connect/connect-rabbitmq-source/rabbitmq-source-ssl.sh index 9f695c51df..642c42fc71 100755 --- a/connect/connect-rabbitmq-source/rabbitmq-source-ssl.sh +++ b/connect/connect-rabbitmq-source/rabbitmq-source-ssl.sh @@ -5,8 +5,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh cd ../../connect/connect-rabbitmq-source/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/ && chmod a+r /tmp/*" +playground tools certs-create --output-folder "$PWD" --container connect --container rabbitmq cd - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} diff --git a/connect/connect-rabbitmq-source/security/certs-create.sh b/connect/connect-rabbitmq-source/security/certs-create.sh deleted file mode 100755 index 04573a38ef..0000000000 --- a/connect/connect-rabbitmq-source/security/certs-create.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in connect rabbitmq -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > ${i}_sslkey_creds - echo "confluent" > ${i}_keystore_creds - echo "confluent" > ${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent - - - cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" - keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent - -done diff --git a/connect/connect-splunk-source/docker-compose.plaintext.yml b/connect/connect-splunk-source/docker-compose.plaintext.yml index 5cabefc74e..473c4fb346 100644 --- a/connect/connect-splunk-source/docker-compose.plaintext.yml +++ b/connect/connect-splunk-source/docker-compose.plaintext.yml @@ -4,6 +4,6 @@ services: ports: - "8889:8889" volumes: - - ../../connect/connect-splunk-source/keystore.jks:/tmp/keystore.jks + - ../../connect/connect-splunk-source/security/kafka.splunk.keystore.jks:/tmp/kafka.splunk.keystore.jks environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-splunk-source \ No newline at end of file diff --git a/connect/connect-splunk-source/splunk-source.sh b/connect/connect-splunk-source/splunk-source.sh index 8ce83f9388..fb30561bbf 100755 --- a/connect/connect-splunk-source/splunk-source.sh +++ b/connect/connect-splunk-source/splunk-source.sh @@ -4,19 +4,10 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -KEYSTORE="${DIR}/keystore.jks" -if [ ! -f ${KEYSTORE} ] -then - OLDDIR=$PWD - - log "INFO: the file ${KEYSTORE} file is not present, generating it..." - cd ${DIR}/../../environment/sasl-ssl/security - - log "🔐 Generate keys and certificates used for SSL" - docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/" - cd ${OLDDIR} - cp ${DIR}/../../environment/sasl-ssl/security/kafka.broker.keystore.jks ${DIR}/keystore.jks -fi +mkdir -p ../../connect/connect-splunk-source/security +cd ../../connect/connect-splunk-source/security +playground tools certs-create --output-folder "$PWD" --container splunk +cd - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" @@ -24,16 +15,16 @@ playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker- log "Creating Splunk source connector" playground connector create-or-update --connector splunk-source << EOF { - "connector.class": "io.confluent.connect.SplunkHttpSourceConnector", - "tasks.max": "1", - "kafka.topic": "splunk-source", - "splunk.collector.index.default": "default-index", - "splunk.port": "8889", - "splunk.ssl.key.store.path": "/tmp/keystore.jks", - "splunk.ssl.key.store.password": "confluent", - "confluent.topic.bootstrap.servers": "broker:9092", - "confluent.topic.replication.factor": "1" - } + "connector.class": "io.confluent.connect.SplunkHttpSourceConnector", + "tasks.max": "1", + "kafka.topic": "splunk-source", + "splunk.collector.index.default": "default-index", + "splunk.port": "8889", + "splunk.ssl.key.store.path": "/tmp/kafka.splunk.keystore.jks", + "splunk.ssl.key.store.password": "confluent", + "confluent.topic.bootstrap.servers": "broker:9092", + "confluent.topic.replication.factor": "1" +} EOF sleep 5 @@ -44,5 +35,4 @@ curl -k -X POST https://localhost:8889/services/collector/event -d '{"event":"fr sleep 5 log "Verifying topic splunk-source" -playground topic consume --topic splunk-source --min-expected-messages 1 --timeout 60 - +playground topic consume --topic splunk-source --min-expected-messages 1 --timeout 60 \ No newline at end of file diff --git a/environment/2way-ssl/start.sh b/environment/2way-ssl/start.sh index 19a88488ad..65d014ce34 100755 --- a/environment/2way-ssl/start.sh +++ b/environment/2way-ssl/start.sh @@ -23,11 +23,7 @@ then fi set_profiles -OLDDIR=$PWD -cd ${OLDDIR}/../../environment/2way-ssl/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/" -cd ${OLDDIR} +playground tools certs-create --output-folder "${PWD}/../../environment/2way-ssl/security" docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/2way-ssl/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} build docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/2way-ssl/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} down -v --remove-orphans diff --git a/environment/sasl-ssl/security/certs-create.sh b/environment/sasl-ssl/security/certs-create.sh index a2948f8ed0..0a16874028 100755 --- a/environment/sasl-ssl/security/certs-create.sh +++ b/environment/sasl-ssl/security/certs-create.sh @@ -9,7 +9,7 @@ rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile # Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent +openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent -provider base for i in broker broker2 broker3 client schema-registry restproxy connect connect2 connect3 control-center clientrestproxy ksqldb-server conduktor do @@ -44,7 +44,7 @@ DNS.1 = $i DNS.2 = localhost EOF # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile + openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile -provider base #openssl x509 -noout -text -in $i-ca1-signed.crt @@ -69,9 +69,9 @@ EOF # openssl rsa -noout -modulus -in client.key | openssl md5 # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem + openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem -provider base keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent + openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent -provider base -nomacver cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" @@ -82,7 +82,7 @@ done # https://stackoverflow.com/a/8224863 openssl pkcs12 -export -in /tmp/clientrestproxy-ca1-signed.crt -inkey /tmp/clientrestproxy.key \ -out /tmp/clientrestproxy.p12 -name clientrestproxy \ - -CAfile /tmp/snakeoil-ca-1.crt -caname CARoot -passout pass:confluent + -CAfile /tmp/snakeoil-ca-1.crt -caname CARoot -passout pass:confluent -provider base --nomac keytool -importkeystore \ -deststorepass confluent -destkeypass confluent -destkeystore /tmp/kafka.restproxy.keystore.jks \ diff --git a/environment/sasl-ssl/start.sh b/environment/sasl-ssl/start.sh index 860be87f54..70f30046d9 100755 --- a/environment/sasl-ssl/start.sh +++ b/environment/sasl-ssl/start.sh @@ -11,11 +11,7 @@ check_docker_compose_version check_bash_version check_playground_version -OLDDIR=$PWD -cd ${OLDDIR}/../../environment/sasl-ssl/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/" -cd ${OLDDIR}/../../environment/sasl-ssl +playground tools certs-create --output-folder "${PWD}/../../environment/sasl-ssl/security" nb_connect_services=0 ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE="" diff --git a/environment/ssl_kerberos/start.sh b/environment/ssl_kerberos/start.sh index dc1d3dd91a..30396b17d4 100755 --- a/environment/ssl_kerberos/start.sh +++ b/environment/ssl_kerberos/start.sh @@ -11,13 +11,7 @@ check_docker_compose_version check_bash_version check_playground_version - -OLDDIR=$PWD -cd ${OLDDIR}/../../environment/ssl_kerberos/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/" -cd ${OLDDIR}/../../environment/ssl_kerberos - +playground tools certs-create --output-folder "${PWD}/../../environment/ssl_kerberos/security" # Starting kerberos, # Avoiding starting up all services at the begining to generate the keytab first diff --git a/other/ldap-authorizer-with-ldap-failover/start-ldaps.sh b/other/ldap-authorizer-with-ldap-failover/start-ldaps.sh index b3f8e539f9..9e93c60c0a 100755 --- a/other/ldap-authorizer-with-ldap-failover/start-ldaps.sh +++ b/other/ldap-authorizer-with-ldap-failover/start-ldaps.sh @@ -4,10 +4,8 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -cd ${DIR}/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/" -cd ${DIR} + +playground tools certs-create --output-folder "${PWD}/../../other/ldap-authorizer-with-ldap-failover/security" playground start-environment --environment ldap-authorizer-sasl-plain --docker-compose-override-file "${PWD}/docker-compose.ldap-authorizer-sasl-plain.ldaps.yml" diff --git a/reproduction-models b/reproduction-models index d25236aacc..4c3704b920 160000 --- a/reproduction-models +++ b/reproduction-models @@ -1 +1 @@ -Subproject commit d25236aacc23f7f1196c77af6b995c2bfa715689 +Subproject commit 4c3704b920973dc5a677b6f7b84a49004031f0ac diff --git a/scripts/cli/completions.bash b/scripts/cli/completions.bash index 01399aa3f4..01381e2cdf 100644 --- a/scripts/cli/completions.bash +++ b/scripts/cli/completions.bash @@ -32,14 +32,14 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector open-ccloud-connector-in-browser'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - *'config open-ccloud-connector-in-browser automatically'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; + *'connector open-ccloud-connector-in-browser'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + *'config open-ccloud-connector-in-browser browser'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -48,28 +48,32 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'tcp-proxy toggle-writes-service'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + ;; + *'connector offsets get-offsets-request-status'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tcp-proxy toggle-writes-service'*'--connection-id') + *'tcp-proxy toggle-writes-client'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'topic set-schema-compatibility'*'--compatibility') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") + *'tcp-proxy toggle-reads-service'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; *'connector-plugin search-jar'*'--connector-plugin') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; - *'tcp-proxy toggle-writes-client'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + *'topic set-schema-compatibility'*'--compatibility') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; - *'tcp-proxy toggle-reads-service'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + *'connector offsets get-offsets-request-status'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; *'connector open-ccloud-connector-in-browser'*'-c') @@ -84,10 +88,6 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'connector offsets get-offsets-request-status'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") - ;; - *'ec2 sync-repro-folder ec2-to-local'*'--instance') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; @@ -120,10 +120,6 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'topic produce'*'--key-subject-name-strategy') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") - ;; - *'debug enable-remote-debugging'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -132,35 +128,35 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'schema set-compatibility'*'--compatibility') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") + *'topic produce'*'--key-subject-name-strategy') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") ;; *'config open-ccloud-connector-in-browser'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h automatically browser")" -- "$cur") ;; - *'topic set-schema-compatibility'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'schema set-compatibility'*'--compatibility') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; - *'container set-environment-variables'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector create-or-update'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'debug generate-diagnostics'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector create-or-update'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'topic set-schema-compatibility'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'ec2 sync-repro-folder ec2-to-local'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'container set-environment-variables'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'ec2 sync-repro-folder local-to-ec2'*'-i') + *'ec2 sync-repro-folder ec2-to-local'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; @@ -168,20 +164,20 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'container set-environment-variables'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --env --help --restore-original-values -c -h")" -- "$cur") + *'ec2 sync-repro-folder local-to-ec2'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'container get-properties'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'container set-environment-variables'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --env --help --restore-original-values -c -h")" -- "$cur") ;; *'tcp-proxy toggle-accept-connections'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'ec2 sync-repro-folder ec2-to-local'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + *'container get-properties'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'connector offsets reset'*'--connector') @@ -196,14 +192,22 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'connector show-config-parameters'*'-c') + *'connector select-config'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector select-config'*'--connector') + *'connector show-config-parameters'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; + *'ec2 sync-repro-folder ec2-to-local'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + ;; + + *'cleanup-cloud-resources'*'--resource') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure ccloud salesforce")" -- "$cur") + ;; + *'schema get-compatibility'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; @@ -212,60 +216,48 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'cleanup-cloud-resources'*'--resource') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure ccloud salesforce")" -- "$cur") - ;; - *'connector create-or-update'*'--level') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'connector show-config-parameters'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-refresh --help --only-show-json --open --verbose -c -h -o -v")" -- "$cur") + *'connector offsets get'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector show-config'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'topic produce'*'--compression-codec') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "gzip snappy lz4 zstd")" -- "$cur") ;; *'debug flight-recorder'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector offsets get'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - *'topic set-schema-compatibility'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'topic produce'*'--compression-codec') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "gzip snappy lz4 zstd")" -- "$cur") + *'connector show-config-parameters'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-refresh --help --only-show-json --open --verbose -c -h -o -v")" -- "$cur") ;; - *'tcp-proxy toggle-writes-service'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'connector show-config'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug enable-remote-debugging'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic get-number-records'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'container change-jdk'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic get-number-records'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") - ;; - - *'tcp-proxy delay'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + *'debug enable-remote-debugging'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic produce'*'--validate-config') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") + *'tcp-proxy toggle-writes-service'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; *'tcp-proxy break'*'--connection-id') @@ -276,32 +268,36 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'debug block-traffic'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'tcp-proxy toggle-writes-client'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'connector log-level'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'tcp-proxy delay'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'topic set-schema-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --topic --verbose -h -t -v")" -- "$cur") + *'tools install-vscode-extension'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'topic display-consumer-offsets'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --verbose -h -v")" -- "$cur") + *'connector log-level'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tcp-proxy toggle-writes-client'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'topic produce'*'--validate-config') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") ;; - *'tools install-vscode-extension'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'debug block-traffic'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy toggle-reads-client'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'topic set-schema-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --topic --verbose -h -t -v")" -- "$cur") + ;; + + *'topic display-consumer-offsets'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --verbose -h -v")" -- "$cur") ;; *'tools read-parquet-file'*'--file') @@ -312,26 +308,30 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'connector show-lag'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - *'connector-plugin search-jar'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; - *'debug flight-recorder'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") + *'tcp-proxy toggle-reads-client'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'connector snippets'*'--converter') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "avro protobuf json-schema json json-schema-enabled string bytearray")" -- "$cur") + *'debug flight-recorder'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") ;; *'container change-jdk'*'--version') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "8 11 17 21 22")" -- "$cur") ;; + *'connector show-lag'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'connector snippets'*'--converter') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "avro protobuf json-schema json json-schema-enabled string bytearray")" -- "$cur") + ;; + *'update-version'*'--connector-zip') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") ;; @@ -340,15 +340,11 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") ;; - *'debug generate-diagnostics'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - *'connector restart'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug thread-dump'*'--container') + *'debug generate-diagnostics'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -356,12 +352,8 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic produce'*'--compatibility') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") - ;; - - *'connector create-or-update'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'debug thread-dump'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'container restart'*'--container') @@ -372,36 +364,40 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'connector unpause'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - *'connector create-or-update'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector delete'*'--connector') + *'connector unpause'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container resume'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector create-or-update'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'connector-plugin versions'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") + *'topic produce'*'--compatibility') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; *'connector resume'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; + *'connector-plugin search-jar'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--class --connector-plugin --connector-tag --help -c -h")" -- "$cur") + ;; + + *'connector update'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + *'connector status'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'schema set-normalize'*'--value') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "true false")" -- "$cur") + *'connector-plugin versions'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; *'debug block-traffic'*'--action') @@ -412,32 +408,44 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector-plugin search-jar'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--class --connector-plugin --connector-tag --help -c -h")" -- "$cur") + *'schema set-normalize'*'--value') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "true false")" -- "$cur") ;; - *'connector update'*'--connector') + *'container resume'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + + *'connector delete'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container pause'*'--container') + *'debug heap-dump'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector pause'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'topic get-number-records'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'debug log-level set'*'--level') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; + *'topic consume'*'--key-subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + ;; + *'get-jmx-metrics'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug heap-dump'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'debug generate-diagnostics'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + ;; + + *'connector pause'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'container get-properties'*'-c') @@ -448,44 +456,36 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector log-level'*'--level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") - ;; - - *'debug generate-diagnostics'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'container pause'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'tcp-proxy close-connection'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; + *'tools read-avro-file'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") + ;; + *'connector create-or-update'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --initial-state --level --offsets --package --skip-automatic-connector-config --validate --verbose --wait-for-zero-lag -c -h -l -p -v")" -- "$cur") ;; - *'topic get-number-records'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") - ;; - - *'tools read-avro-file'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") - ;; - - *'topic consume'*'--key-subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'connector log-level'*'--level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; *'connector offsets reset'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container exec'*'--container') + *'tcp-proxy start'*'--hostname') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector stop'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container logs'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'tcp-proxy get-connections'*) @@ -496,58 +496,54 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'repro bootstrap'*'--pipeline') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro --sink-only "$cur")")" -- "$cur") - ;; - - *'container logs'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - *'repro bootstrap'*'--producer') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") ;; - *'ec2 create'*'--instance-type') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "c1.medium c1.xlarge c3.2xlarge c3.4xlarge c3.8xlarge c3.large c3.xlarge c4.2xlarge c4.4xlarge c4.large c4.xlarge m1.large m1.medium m1.small m1.xlarge m2.2xlarge m2.4xlarge m2.xlarge m3.2xlarge m3.large m3.medium m3.xlarge m4.10xlarge m4.2xlarge m4.4xlarge m4.large m4.xlarge t1.micro t2.large t2.medium t2.micro t2.nano t2.small t3.2xlarge")" -- "$cur") + *'connector offsets alter'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'debug block-traffic'*'--port') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'tcp-proxy start'*'--hostname') + *'debug tcp-dump'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'tools read-parquet-file'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") + ;; + + *'ec2 create'*'--instance-type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "c1.medium c1.xlarge c3.2xlarge c3.4xlarge c3.8xlarge c3.large c3.xlarge c4.2xlarge c4.4xlarge c4.large c4.xlarge m1.large m1.medium m1.small m1.xlarge m2.2xlarge m2.4xlarge m2.xlarge m3.2xlarge m3.large m3.medium m3.xlarge m4.10xlarge m4.2xlarge m4.4xlarge m4.large m4.xlarge t1.micro t2.large t2.medium t2.micro t2.nano t2.small t3.2xlarge")" -- "$cur") + ;; + *'config check-repo-version'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; + *'container exec'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + *'connector-plugin versions'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-plugin --force-refresh --help --last -c -h")" -- "$cur") ;; - *'debug tcp-dump'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector stop'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector offsets alter'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'repro bootstrap'*'--pipeline') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro --sink-only "$cur")")" -- "$cur") ;; *'container kill'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tools read-parquet-file'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") - ;; - - *'run'*'--cluster-environment') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-environment-list "$cur")")" -- "$cur") - ;; - *'topic produce'*'--reference') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; @@ -560,60 +556,60 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'remove-all-docker-images'*) + *'config folder_zip_or_jar'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'schema get-mode'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'container ssh'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'schema get-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") + *'run'*'--cluster-environment') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-environment-list "$cur")")" -- "$cur") ;; - *'debug java-debug'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "enable disable")" -- "$cur") + *'topic get-number-records'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") ;; - *'container ssh'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'remove-all-docker-images'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + + *'debug java-debug'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "enable disable")" -- "$cur") ;; *'schema set-mode'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'topic get-number-records'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") + *'schema get-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; - *'schema set-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --subject --verbose -h -v")" -- "$cur") + *'schema get-mode'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'config folder_zip_or_jar'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'schema set-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --subject --verbose -h -v")" -- "$cur") ;; - *'connector offsets alter'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'debug flight-recorder'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector show-config'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'schema register'*'--schema') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; *'connector select-config'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") ;; - *'schema register'*'--schema') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") - ;; - - *'debug flight-recorder'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector offsets get'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'cleanup-cloud-resources'*) @@ -624,84 +620,92 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'connector offsets get'*'-c') + *'tools read-parquet-file'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + ;; + + *'connector offsets alter'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + ;; + + *'connector show-config'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tools read-parquet-file'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + *'container change-jdk'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'schema delete'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'container change-jdk'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'tools read-avro-file'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") ;; *'debug java-debug'*'--type') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ssl_all ssl_handshake class_loading kerberos")" -- "$cur") ;; - *'tools read-avro-file'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") + *'tcp-proxy start'*'--port') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'container exec'*'--shell') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") + *'connector log-level'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'connector show-config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-rest-endpoint --help --verbose -c -h -v")" -- "$cur") + *'schema set-mode'*'--mode') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") ;; - *'cleanup-cloud-details'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'connector log-level'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'topic describe'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'container exec'*'--shell') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'ec2 sync-repro-folder'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h ec2-to-local local-to-ec2")" -- "$cur") + *'connector offsets get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'schema set-mode'*'--mode') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") + *'ec2 sync-repro-folder'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h ec2-to-local local-to-ec2")" -- "$cur") ;; - *'connector log-level'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug block-traffic'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy start'*'--port') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") + *'debug flight-recorder'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help -c -h")" -- "$cur") ;; *'repro bootstrap'*'--file') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") ;; - *'debug log-level set'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'cleanup-cloud-details'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector offsets get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'debug log-level set'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'debug block-traffic'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic describe'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector log-level'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'connector show-config'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-rest-endpoint --help --verbose -c -h -v")" -- "$cur") ;; - *'debug flight-recorder'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help -c -h")" -- "$cur") + *'ec2 delete'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") ;; *'topic produce'*'--topic') @@ -712,24 +716,24 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'connector show-lag'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'topic consume'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'tools read-avro-file'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + *'connector show-lag'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'schema set-normalize'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --value --verbose -h -v")" -- "$cur") ;; - *'ec2 delete'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") + *'tools read-avro-file'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'topic consume'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'debug tcp-dump'*'--port') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; *'container ssh'*'--shell') @@ -740,115 +744,119 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --version -c -h")" -- "$cur") ;; - *'debug tcp-dump'*'--port') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") + *'connector open-docs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") ;; - *'update-version'*'--tag') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") + *'debug log-level set'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --level --package -h -l -p")" -- "$cur") ;; - *'schema get'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'connector log-level'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level -c -h -l")" -- "$cur") ;; - *'ec2 start'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'debug log-level get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --package -h -p")" -- "$cur") ;; *'run'*'--cluster-region') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-kafka-region-list "$cur")")" -- "$cur") ;; - *'connector restart'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'update-version'*'--tag') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") ;; - *'connector unpause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug block-traffic'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --destination --help --port -c -h")" -- "$cur") ;; *'topic delete'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector open-docs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") + *'connector unpause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug log-level set'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --level --package -h -l -p")" -- "$cur") + *'schema get'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'debug log-level get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --package -h -p")" -- "$cur") + *'ec2 start'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'connector log-level'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level -c -h -l")" -- "$cur") + *'connector restart'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug thread-dump'*'-c') + *'container restart'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container restart'*'-c') + *'container unpause'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container unpause'*'-c') + *'debug thread-dump'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug block-traffic'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --destination --help --port -c -h")" -- "$cur") + *'connector show-lag'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --interval --max-wait --verbose -c -h -v")" -- "$cur") ;; - *'run'*'--cluster-cloud') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure")" -- "$cur") + *'repro import'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") ;; - *'topic alter'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'connector status'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector versions'*) + *'get-docker-compose'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector status'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug java-debug'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector resume'*'-c') + *'connector delete'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'topic produce'*'--key') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + *'connector snippets'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--converter --dlq --help -h")" -- "$cur") ;; - *'ec2 stop'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'tools certs-create'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --output-folder --verbose -h -v")" -- "$cur") ;; - *'ec2 open'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'topic alter'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector delete'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'topic produce'*'--key') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'connector show-lag'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --interval --max-wait --verbose -c -h -v")" -- "$cur") + *'connector versions'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector update'*'-c') + *'connector resume'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'get-docker-compose'*) + *'container recreate'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --ignore-current-versions -h")" -- "$cur") + ;; + + *'container kill-all'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -856,128 +864,128 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug java-debug'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'run'*'--cluster-cloud') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure")" -- "$cur") ;; - *'connector snippets'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--converter --dlq --help -h")" -- "$cur") + *'connector update'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container recreate'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --ignore-current-versions -h")" -- "$cur") + *'ec2 open'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'repro import'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") + *'ec2 stop'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + ;; + + *'run'*'--connector-jar') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") ;; *'run'*'--connector-zip') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") ;; - *'container kill-all'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'run'*'--cluster-name') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") ;; - *'run'*'--connector-jar') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") + *'debug thread-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'connector plugins'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help --verbose -h -v")" -- "$cur") + *'connector unpause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'debug heap-dump'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'repro bootstrap'*'-p') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") ;; - *'get-jmx-metrics'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector offsets'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter get get-offsets-request-status reset")" -- "$cur") ;; - *'debug thread-dump'*) + *'container restart'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'connector offsets'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter get get-offsets-request-status reset")" -- "$cur") + *'container unpause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'repro bootstrap'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") + *'connector restart'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + ;; + + *'connector pause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'connector plugins'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help --verbose -h -v")" -- "$cur") ;; - *'repro bootstrap'*'-p') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") + *'container pause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'run'*'--cluster-name') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") + *'get-jmx-metrics'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'run'*'--cluster-type') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "basic standard dedicated")" -- "$cur") ;; - *'connector unpause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") - ;; - - *'connector pause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'repro bootstrap'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") ;; - *'connector restart'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'debug heap-dump'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container unpause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'config clipboard'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'container restart'*) + *'container resume'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'container pause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'debug java-debug'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help --type -c -h")" -- "$cur") ;; *'topic describe'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'debug tcp-dump'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container kill'*'-c') + *'container logs'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector update'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") + *'connector stop'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'connector resume'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'container resume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") - ;; - - *'connector stop'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'config clipboard'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'connector update'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") ;; - *'run'*'--environment') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") + *'container kill'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'container exec'*'-c') @@ -988,44 +996,36 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'container logs'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'debug tcp-dump'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'debug java-debug'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help --type -c -h")" -- "$cur") + *'run'*'--environment') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") ;; *'connector-plugin'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h search-jar versions")" -- "$cur") ;; - *'connector pause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") - ;; - - *'get-jmx-metrics'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --domain --help --open -c -d -h -o")" -- "$cur") + *'repro bootstrap'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--custom-smt --description --file --help --pipeline -d -f -h")" -- "$cur") ;; - *'tcp-proxy break'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") + *'connector pause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'tcp-proxy delay'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") + *'topic consume'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'tcp-proxy start'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --delay-service-response --help --hostname --port --service-response-corrupt --skip-automatic-connector-config --throttle-service-response -h")" -- "$cur") + *'debug heap-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") ;; - *'debug log-level'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h get set")" -- "$cur") + *'container pause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; *'container ssh'*'-c') @@ -1036,126 +1036,130 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'container pause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") - ;; - - *'schema register'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --metadata-property --schema --subject --verbose -h -v")" -- "$cur") - ;; - - *'debug heap-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") + *'tcp-proxy break'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") ;; - *'schema set-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") + *'tcp-proxy delay'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") ;; - *'repro bootstrap'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--custom-smt --description --file --help --pipeline -d -f -h")" -- "$cur") + *'get-jmx-metrics'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --domain --help --open -c -d -h -o")" -- "$cur") ;; - *'topic consume'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'tcp-proxy start'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --delay-service-response --help --hostname --port --service-response-corrupt --skip-automatic-connector-config --throttle-service-response -h")" -- "$cur") ;; *'topic produce'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'schema get-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") + *'debug log-level'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h get set")" -- "$cur") ;; - *'update-version'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-jar --connector-tag --connector-zip --help --tag -h")" -- "$cur") + *'schema set-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") ;; - *'topic describe'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") + *'schema get-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; - *'container logs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") + *'schema register'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --metadata-property --schema --subject --verbose -h -v")" -- "$cur") ;; - *'connector stop'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'container kill'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; *'connector logs'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") ;; + *'update-version'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-jar --connector-tag --connector-zip --help --tag -h")" -- "$cur") + ;; + *'debug tcp-dump'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --duration --help --port -c -h")" -- "$cur") ;; - *'container kill'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'repro import'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") ;; - *'container exec'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--command --container --help --root --shell -c -h")" -- "$cur") + *'container logs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") ;; - *'topic delete'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'topic describe'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") ;; - *'repro import'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") + *'topic delete'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'--output-level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") + *'connector stop'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'config editor'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'container exec'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--command --container --help --root --shell -c -h")" -- "$cur") ;; *'container ssh'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") ;; - *'switch-ccloud'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'topic consume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--grep --help --key-subject --max-characters --max-messages --min-expected-messages --plot-latencies-timestamp-field --tail --timeout --topic --value-subject --verbose -h -t -v")" -- "$cur") ;; *'topic alter'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'schema delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --permanent --subject --verbose --version -h -v")" -- "$cur") + *'debug testssl'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'debug testssl'*) + *'config editor'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'topic consume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--grep --help --key-subject --max-characters --max-messages --min-expected-messages --plot-latencies-timestamp-field --tail --timeout --topic --value-subject --verbose -h -t -v")" -- "$cur") + *'switch-ccloud'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'topic produce'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --max-nb-messages-to-generate --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") ;; - *'repro export'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help -h")" -- "$cur") + *'--output-level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") ;; - *'repro import'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + *'schema delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --permanent --subject --verbose --version -h -v")" -- "$cur") ;; *'ec2 delete'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") ;; + *'repro export'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help -h")" -- "$cur") + ;; + + *'repro import'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + ;; + *'topic create'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --nb-partitions --topic --verbose -h -t -v")" -- "$cur") ;; @@ -1164,52 +1168,44 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --skip-delete-schema --topic --verbose -h -t -v")" -- "$cur") ;; - *'ec2 start'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") - ;; - *'switch-back'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; + *'ec2 start'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + ;; + *'topic alter'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") ;; - *'ec2 create'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance-type --size --suffix -h")" -- "$cur") + *'schema get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") ;; *'ec2 delete'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'ec2 open'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'ec2 create'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance-type --size --suffix -h")" -- "$cur") ;; - *'ec2 stop'*'-i') + *'ec2 open'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'schema get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") - ;; - *'topic list'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'open'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") - ;; - - *'connector'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create-or-update delete log-level logs offsets open-ccloud-connector-in-browser open-docs pause plugins restart resume select-config show-config show-config-parameters show-lag snippets status stop unpause update versions")" -- "$cur") + *'ec2 stop'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'ec2 start'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + *'open'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") ;; *'container'*) @@ -1224,12 +1220,16 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") ;; + *'connector'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create-or-update delete log-level logs offsets open-ccloud-connector-in-browser open-docs pause plugins restart resume select-config show-config show-config-parameters show-lag snippets status stop unpause update versions")" -- "$cur") + ;; + *'tcp-proxy'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h break close-all-connection-with-error close-connection delay get-connections start toggle-accept-connections toggle-reads-client toggle-reads-service toggle-writes-client toggle-writes-service")" -- "$cur") ;; - *'ec2 open'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--disable-sync-repro-folder --help --instance -h -i")" -- "$cur") + *'ec2 start'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; *'run'*'--tag') @@ -1244,32 +1244,36 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; + *'ec2 open'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--disable-sync-repro-folder --help --instance -h -i")" -- "$cur") + ;; + *'history'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h check-repo-version clipboard container-kill-all-before-run editor folder_zip_or_jar open-ccloud-connector-in-browser")" -- "$cur") + *'schema'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h delete get get-compatibility get-mode register set-compatibility set-mode set-normalize")" -- "$cur") ;; *'status'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'schema'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h delete get get-compatibility get-mode register set-compatibility set-mode set-normalize")" -- "$cur") - ;; - - *'open'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") + *'config'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h check-repo-version clipboard container-kill-all-before-run editor folder_zip_or_jar open-ccloud-connector-in-browser")" -- "$cur") ;; *'re-run'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; + *'open'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") + ;; + *'tools'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h install-vscode-extension read-avro-file read-parquet-file")" -- "$cur") + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h certs-create install-vscode-extension read-avro-file read-parquet-file")" -- "$cur") ;; *'debug'*) diff --git a/scripts/cli/playground b/scripts/cli/playground index cdfe04c4fc..cbedeb2ea5 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -89,6 +89,7 @@ playground_usage() { printf " %s 🪄 Install a slightly modified version of \"Shell Script Command Completion\" Visual Studio Code extension (https://marketplace.visualstudio.com/items?itemName=tetradresearch.vscode-h2o)\n" "$(green "tools install-vscode-extension") " printf " %s 🔖 Read provided avro file\n" "$(green "tools read-avro-file") " printf " %s 🔖 Read provided parquet file\n" "$(green "tools read-parquet-file") " + printf " %s 🔐 Generate keys and certificates used for SSL\n" "$(green "tools certs-create") " echo printf "%s\n" "$(bold "Debug commands:")" printf " %s 🐞 Debug commands\n" "$(green "debug") " @@ -3032,6 +3033,7 @@ playground_tools_usage() { printf " %s 🪄 Install a slightly modified version of \"Shell Script Command Completion\" Visual Studio Code extension (https://marketplace.visualstudio.com/items?itemName=tetradresearch.vscode-h2o)\n" "$(green "install-vscode-extension")" printf " %s 🔖 Read provided avro file\n" "$(green "read-avro-file") " printf " %s 🔖 Read provided parquet file\n" "$(green "read-parquet-file") " + printf " %s 🔐 Generate keys and certificates used for SSL\n" "$(green "certs-create") " echo # :command.long_usage @@ -3131,6 +3133,44 @@ playground_tools_read_parquet_file_usage() { fi } +# :command.usage +playground_tools_certs_create_usage() { + printf "playground tools certs-create - 🔐 Generate keys and certificates used for SSL\n\n" + + printf "%s\n" "$(bold "== Usage ==")" + printf " playground tools certs-create [OPTIONS]\n" + printf " playground tools certs-create --help | -h\n" + echo + + # :command.long_usage + if [[ -n "$long_usage" ]]; then + printf "%s\n" "$(bold "== Options ==")" + + # :command.usage_flags + # :flag.usage + printf " %s\n" "$(magenta "--container CONTAINER (repeatable)")" + printf " 🐳 container name\n \n 🎓 Tip: you can pass multiple containers by specifying --container multiple\n times\n" + printf " %s\n" "Default: broker, broker2, broker3, client, schema-registry, restproxy, connect, connect2, connect3, control-center, clientrestproxy, ksqldb-server, conduktor" + echo + + # :flag.usage + printf " %s\n" "$(magenta "--verbose, -v")" + printf " 🐞 Show command being ran.\n" + echo + + # :flag.usage + printf " %s\n" "$(magenta "--output-folder FOLDER (required)")" + printf " 📁 Folder where certificates are created\n" + echo + + # :command.usage_fixed_flags + printf " %s\n" "$(magenta "--help, -h")" + printf " Show this help\n" + echo + + fi +} + # :command.usage playground_debug_usage() { printf "playground debug - 🐞 Debug commands\n\n" @@ -18817,6 +18857,39 @@ playground_tools_read_parquet_file_command() { } +# :command.function +playground_tools_certs_create_command() { + # src/commands/tools/certs-create.sh + output_folder="${args[--output-folder]}" + verbose="${args[--verbose]}" + # Convert the space delimited string to an array + eval "containers=(${args[--container]})" + + function cleanup { + set +e + rm -f "${output_folder}/certs-create.sh" + } + trap cleanup EXIT + + maybe_redirect_output="> /dev/null 2>&1" + if [[ -n "$verbose" ]] + then + maybe_redirect_output="" + fi + + container_list="${containers[*]}" + + new_open_ssl=0 + if version_gt $CONNECT_TAG "7.7.99" + then + new_open_ssl=1 + fi + cd "${output_folder}" + cp $root_folder/scripts/cli/src/ssl/certs-create.sh . + log "🔐 Generate keys and certificates in folder ${output_folder}" + docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" +} + # :command.function playground_debug_enable_remote_debugging_command() { # src/commands/debug/enable-remote-debugging.sh @@ -32093,6 +32166,13 @@ playground_tools_parse_requirements() { shift $# ;; + certs-create) + action="certs-create" + shift + playground_tools_certs_create_parse_requirements "$@" + shift $# + ;; + # :command.command_fallback "") playground_tools_usage >&2 @@ -32313,6 +32393,108 @@ playground_tools_read_parquet_file_parse_requirements() { } +# :command.parse_requirements +playground_tools_certs_create_parse_requirements() { + # :command.fixed_flags_filter + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + --help | -h) + long_usage=yes + playground_tools_certs_create_usage + exit + ;; + + *) + break + ;; + + esac + done + + # :command.command_filter + action="tools certs-create" + + # :command.parse_requirements_while + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + # :flag.case + --container) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + escaped="$(printf '%q' "$2")" + if [[ -z ${args['--container']+x} ]]; then + args['--container']="$escaped" + elif [[ -z "${unique_lookup["--container:${escaped}"]:-}" ]]; then + args['--container']="${args['--container']} $escaped" + fi + unique_lookup["--container:${escaped}"]=1 + shift + shift + else + printf "%s\n" "--container requires an argument: --container CONTAINER" >&2 + exit 1 + fi + ;; + + # :flag.case + --verbose | -v) + + # :flag.case_no_arg + args['--verbose']=1 + shift + ;; + + # :flag.case + --output-folder) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + args['--output-folder']="$2" + shift + shift + else + printf "%s\n" "--output-folder requires an argument: --output-folder FOLDER" >&2 + exit 1 + fi + ;; + + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; + + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + printf "invalid argument: %s\n" "$key" >&2 + exit 1 + + ;; + + esac + done + + # :command.required_flags_filter + if [[ -z ${args['--output-folder']+x} ]]; then + printf "missing required flag: --output-folder FOLDER\n" >&2 + exit 1 + fi + + # :command.default_assignments + [[ -n ${args['--container']:-} ]] || args['--container']="broker broker2 broker3 client schema-registry restproxy connect connect2 connect3 control-center clientrestproxy ksqldb-server conduktor" + + # :command.validations + # :flag.validations + if [[ -v args['--output-folder'] && -n $(validate_dir_exists "${args['--output-folder']:-}") ]]; then + printf "validation error in %s:\n%s\n" "--output-folder FOLDER" "$(validate_dir_exists "${args['--output-folder']:-}")" >&2 + exit 1 + fi + +} + # :command.parse_requirements playground_debug_parse_requirements() { # :command.fixed_flags_filter @@ -39466,6 +39648,7 @@ run() { "tools install-vscode-extension") playground_tools_install_vscode_extension_command ;; "tools read-avro-file") playground_tools_read_avro_file_command ;; "tools read-parquet-file") playground_tools_read_parquet_file_command ;; + "tools certs-create") playground_tools_certs_create_command ;; "debug") playground_debug_command ;; "debug enable-remote-debugging") playground_debug_enable_remote_debugging_command ;; "debug testssl") playground_debug_testssl_command ;; diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index 0fa67f4ee2..75c828ac71 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -1050,6 +1050,49 @@ "description": "🔖 Parquet file to read\n\n❕ It must be absolute full path\n\n🎓 Tip: use completion to trigger fzf completion\n" } ] + }, + { + "name": "certs-create", + "description": "🔐 Generate keys and certificates used for SSL\n", + "usage": "playground tools certs-create [OPTIONS]", + "options": [ + { + "names": [ + "--container" + ], + "argument": [ + "broker", + "broker2", + "broker3", + "client", + "schema-registry", + "restproxy", + "connect", + "connect2", + "connect3", + "control-center", + "clientrestproxy", + "ksqldb-server", + "conduktor" + ], + "description": "🐳 container name\n\n🎓 Tip: you can pass multiple containers by specifying --container multiple times\n\nRepeatable: ✓ Yes\n\nDefault value: [\"broker\", \"broker2\", \"broker3\", \"client\", \"schema-registry\", \"restproxy\", \"connect\", \"connect2\", \"connect3\", \"control-center\", \"clientrestproxy\", \"ksqldb-server\", \"conduktor\"]\n" + }, + { + "names": [ + "--verbose", + "-v" + ], + "argument": "", + "description": "🐞 Show command being ran.\n" + }, + { + "names": [ + "--output-folder" + ], + "argument": "FOLDER", + "description": "📁 Folder where certificates are created\n\nRequired: ✓ Yes\n" + } + ] } ] }, diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index 3aa80e67ba..170d47ff81 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -1183,6 +1183,38 @@ subcommands: 🎓 Tip: use completion to trigger fzf completion + - name: certs-create + description: | + 🔐 Generate keys and certificates used for SSL + usage: playground tools certs-create [OPTIONS] + options: + - names: + - --container + argument: ["broker", "broker2", "broker3", "client", "schema-registry", "restproxy", "connect", "connect2", "connect3", "control-center", "clientrestproxy", "ksqldb-server", "conduktor"] + description: | + 🐳 container name + + 🎓 Tip: you can pass multiple containers by specifying --container multiple times + + Repeatable: ✓ Yes + + Default value: ["broker", "broker2", "broker3", "client", "schema-registry", "restproxy", "connect", "connect2", "connect3", "control-center", "clientrestproxy", "ksqldb-server", "conduktor"] + + - names: + - --verbose + - -v + argument: "" + description: | + 🐞 Show command being ran. + + - names: + - --output-folder + argument: FOLDER + description: | + 📁 Folder where certificates are created + + Required: ✓ Yes + - name: debug description: | 🐞 Debug commands diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index d587d3f59f..bfb257c7ca 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -1580,6 +1580,41 @@ commands: 🎓 Tip: use completion to trigger fzf completion + - name: certs-create + help: |- + 🔐 Generate keys and certificates used for SSL + flags: + - long: --container + arg: container + help: |- + 🐳 container name + + 🎓 Tip: you can pass multiple containers by specifying --container multiple times + required: false + repeatable: true + unique: true + default: + - broker + - broker2 + - broker3 + - client + - schema-registry + - restproxy + - connect + - connect2 + - connect3 + - control-center + - clientrestproxy + - ksqldb-server + - conduktor + - *verbose + - long: --output-folder + required: true + validate: dir_exists + arg: folder + help: |- + 📁 Folder where certificates are created + - name: debug expose: always group: Debug diff --git a/scripts/cli/src/commands/tools/certs-create.sh b/scripts/cli/src/commands/tools/certs-create.sh new file mode 100644 index 0000000000..c0d7ed4c89 --- /dev/null +++ b/scripts/cli/src/commands/tools/certs-create.sh @@ -0,0 +1,28 @@ +output_folder="${args[--output-folder]}" +verbose="${args[--verbose]}" +# Convert the space delimited string to an array +eval "containers=(${args[--container]})" + +function cleanup { + set +e + rm -f "${output_folder}/certs-create.sh" +} +trap cleanup EXIT + +maybe_redirect_output="> /dev/null 2>&1" +if [[ -n "$verbose" ]] +then + maybe_redirect_output="" +fi + +container_list="${containers[*]}" + +new_open_ssl=0 +if version_gt $CONNECT_TAG "7.7.99" +then + new_open_ssl=1 +fi +cd "${output_folder}" +cp $root_folder/scripts/cli/src/ssl/certs-create.sh . +log "🔐 Generate keys and certificates in folder ${output_folder}" +docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" \ No newline at end of file diff --git a/scripts/cli/src/openssl.cnf b/scripts/cli/src/openssl.cnf new file mode 100644 index 0000000000..6c1bd1cb8c --- /dev/null +++ b/scripts/cli/src/openssl.cnf @@ -0,0 +1,392 @@ +# OpenSSL example configuration file. +# See doc/man5/config.pod for more info. +# +# This is mostly being used for generation of certificate requests, +# but may be used for auto loading of providers + +# Note that you can include other files from the main configuration +# file using the .include directive. +#.include filename + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . + + # Use this in order to automatically load providers. +openssl_conf = openssl_init + +# Comment out the next line to ignore configuration errors +config_diagnostics = 1 + +# Extra OBJECT IDENTIFIER info: +# oid_file = $ENV::HOME/.oid +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] +# We can add new OIDs in here for use by 'ca', 'req' and 'ts'. +# Add a simple OID like this: +# testoid1=1.2.3.4 +# Or use config file substitution like this: +# testoid2=${testoid1}.5.6 + +# Policies used by the TSA examples. +tsa_policy1 = 1.2.3.4.1 +tsa_policy2 = 1.2.3.4.5.6 +tsa_policy3 = 1.2.3.4.5.7 + +# For FIPS +# Optionally include a file that is generated by the OpenSSL fipsinstall +# application. This file contains configuration data required by the OpenSSL +# fips provider. It contains a named section e.g. [fips_sect] which is +# activate=0 +# referenced from the [provider_sect] below. +# Refer to the OpenSSL security policy for more information. +# .include fipsmodule.cnf +.include /usr/local/ssl/fipsmodule.cnf + +[openssl_init] +providers = provider_sect + +# List of providers to load +[provider_sect] +fips = fips_sect +# The fips section name should match the section name inside the +# included fipsmodule.cnf. +# fips = fips_sect + +# If no providers are activated explicitly, the default one is activated implicitly. +# See man 7 OSSL_PROVIDER-default for more details. +# +# If you add a section explicitly activating any other provider(s), you most +# probably need to explicitly activate the default provider, otherwise it +# becomes unavailable in openssl. As a consequence applications depending on +# OpenSSL may not work correctly which could lead to significant system +# problems including inability to remotely access the system. +[fips_sect] +activate = 1 +# activate = 1 + + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = ./demoCA # Where everything is kept +certs = $dir/certs # Where the issued certs are kept +crl_dir = $dir/crl # Where the issued crl are kept +database = $dir/index.txt # database index file. +#unique_subject = no # Set to 'no' to allow creation of + # several certs with same subject. +new_certs_dir = $dir/newcerts # default place for new certs. + +certificate = $dir/cacert.pem # The CA certificate +serial = $dir/serial # The current serial number +crlnumber = $dir/crlnumber # the current crl number + # must be commented out to leave a V1 CRL +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/cakey.pem# The private key + +x509_extensions = usr_cert # The extensions to add to the cert + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +# crl_extensions = crl_ext + +default_days = 365 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = default # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +#################################################################### +[ req ] +default_bits = 2048 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extensions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = AU +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = Some-State + +localityName = Locality Name (eg, city) + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = Internet Widgits Pty Ltd + +# we can do this but it is not needed normally :-) +#1.organizationName = Second Organization Name (eg, company) +#1.organizationName_default = World Wide Web Pty Ltd + +organizationalUnitName = Organizational Unit Name (eg, section) +#organizationalUnitName_default = + +commonName = Common Name (e.g. server FQDN or YOUR name) +commonName_max = 64 + +emailAddress = Email Address +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 + +unstructuredName = An optional company name + +[ usr_cert ] + +# These extensions are added when 'ca' signs a request. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +# This is required for TSA certificates. +# extendedKeyUsage = critical,timeStamping + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] + + +# Extensions for a typical CA + + +# PKIX recommendation. + +subjectKeyIdentifier=hash + +authorityKeyIdentifier=keyid:always,issuer + +basicConstraints = critical,CA:true + +# Key usage: this is typical for a CA certificate. However since it will +# prevent it being used as an test self-signed certificate it is best +# left out by default. +# keyUsage = cRLSign, keyCertSign + +# Include email address in subject alt name: another PKIX recommendation +# subjectAltName=email:copy +# Copy issuer details +# issuerAltName=issuer:copy + +# DER hex encoding of an extension: beware experts only! +# obj=DER:02:03 +# Where 'obj' is a standard or added object +# You can even override a supported extension: +# basicConstraints= critical, DER:30:03:01:01:FF + +[ crl_ext ] + +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +[ proxy_cert_ext ] +# These extensions should be added when creating a proxy certificate + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +# This really needs to be in place for it to be a proxy certificate. +proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo + +#################################################################### +[ tsa ] + +default_tsa = tsa_config1 # the default TSA section + +[ tsa_config1 ] + +# These are used by the TSA reply generation only. +dir = ./demoCA # TSA root directory +serial = $dir/tsaserial # The current serial number (mandatory) +crypto_device = builtin # OpenSSL engine to use for signing +signer_cert = $dir/tsacert.pem # The TSA signing certificate + # (optional) +certs = $dir/cacert.pem # Certificate chain to include in reply + # (optional) +signer_key = $dir/private/tsakey.pem # The TSA private key (optional) +signer_digest = sha256 # Signing digest to use. (Optional) +default_policy = tsa_policy1 # Policy if request did not specify it + # (optional) +other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) +digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory) +accuracy = secs:1, millisecs:500, microsecs:100 # (optional) +clock_precision_digits = 0 # number of digits after dot. (optional) +ordering = yes # Is ordering defined for timestamps? + # (optional, default: no) +tsa_name = yes # Must the TSA name be included in the reply? + # (optional, default: no) +ess_cert_id_chain = no # Must the ESS cert id chain be included? + # (optional, default: no) +ess_cert_id_alg = sha1 # algorithm to compute certificate + # identifier (optional, default: sha1) + +[insta] # CMP using Insta Demo CA +# Message transfer +server = pki.certificate.fi:8700 +# proxy = # set this as far as needed, e.g., http://192.168.1.1:8080 +# tls_use = 0 +path = pkix/ + +# Server authentication +recipient = "/C=FI/O=Insta Demo/CN=Insta Demo CA" # or set srvcert or issuer +ignore_keyusage = 1 # potentially needed quirk +unprotected_errors = 1 # potentially needed quirk +extracertsout = insta.extracerts.pem + +# Client authentication +ref = 3078 # user identification +secret = pass:insta # can be used for both client and server side + +# Generic message options +cmd = ir # default operation, can be overridden on cmd line with, e.g., kur + +# Certificate enrollment +subject = "/CN=openssl-cmp-test" +newkey = insta.priv.pem +out_trusted = apps/insta.ca.crt # does not include keyUsage digitalSignature +certout = insta.cert.pem + +[pbm] # Password-based protection for Insta CA +# Server and client authentication +ref = $insta::ref # 3078 +secret = $insta::secret # pass:insta + +[signature] # Signature-based protection for Insta CA +# Server authentication +trusted = $insta::out_trusted # apps/insta.ca.crt + +# Client authentication +secret = # disable PBM +key = $insta::newkey # insta.priv.pem +cert = $insta::certout # insta.cert.pem + +[ir] +cmd = ir + +[cr] +cmd = cr + +[kur] +# Certificate update +cmd = kur +oldcert = $insta::certout # insta.cert.pem + +[rr] +# Certificate revocation +cmd = rr +oldcert = $insta::certout # insta.cert.pem diff --git a/scripts/cli/src/ssl/certs-create.sh b/scripts/cli/src/ssl/certs-create.sh new file mode 100755 index 0000000000..a2f1733515 --- /dev/null +++ b/scripts/cli/src/ssl/certs-create.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +# Split the argument into an array +IFS=' ' read -r -a containers <<< "$1" +new_open_ssl=$2 + +if [[ $new_open_ssl -eq 1 ]] +then + maybe_provider="-provider base" + maybe_nomacver="-nomacver" + maybe_nomac="--nomac" +else + maybe_provider="" + maybe_nomacver="" + maybe_nomac="" +fi + +# Cleanup files +rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile + +# Generate CA key +openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent $maybe_provider + +for container in "${containers[@]}" +do + # Create host keystore + keytool -genkey -noprompt \ + -alias ${container} \ + -dname "CN=${container},OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ + -ext "SAN=dns:${container},dns:localhost" \ + -keystore /tmp/kafka.${container}.keystore.jks \ + -keyalg RSA \ + -storepass confluent \ + -keypass confluent \ + -storetype pkcs12 + + # Create the certificate signing request (CSR) + keytool -keystore /tmp/kafka.${container}.keystore.jks -alias ${container} -certreq -file /tmp/${container}.csr -storepass confluent -keypass confluent -ext "SAN=dns:${container},dns:localhost" + #openssl req -in ${container}.csr -text -noout + +cat << EOF > /tmp/extfile +[req] +distinguished_name = req_distinguished_name +x509_extensions = v3_req +prompt = no +[req_distinguished_name] +CN = ${container} +[v3_req] +subjectAltName = @alt_names +[alt_names] +DNS.1 = ${container} +DNS.2 = localhost +EOF + # Sign the host certificate with the certificate authority (CA) + openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/${container}.csr -out /tmp/${container}-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile $maybe_provider + + # Sign and import the CA cert into the keystore + keytool -noprompt -keystore /tmp/kafka.${container}.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent + + # Sign and import the host certificate into the keystore + keytool -noprompt -keystore /tmp/kafka.${container}.keystore.jks -alias ${container} -import -file /tmp/${container}-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:${container},dns:localhost" + + # Create truststore and import the CA cert + keytool -noprompt -keystore /tmp/kafka.${container}.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent + + # Save creds + echo "confluent" > /tmp/${i}_sslkey_creds + echo "confluent" > /tmp/${i}_keystore_creds + echo "confluent" > /tmp/${i}_truststore_creds + + # Create pem files and keys used for Schema Registry HTTPS testing + keytool -export -alias ${container} -file /tmp/${container}.der -keystore /tmp/kafka.${container}.keystore.jks -storepass confluent + openssl x509 -inform der -in /tmp/${container}.der -out /tmp/${container}.certificate.pem $maybe_provider + keytool -importkeystore -srckeystore /tmp/kafka.${container}.keystore.jks -destkeystore /tmp/${container}.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt + openssl pkcs12 -in /tmp/${container}.keystore.p12 -nodes -nocerts -out /tmp/${container}.key -passin pass:confluent $maybe_provider $maybe_nomacver + + + cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" + keytool -noprompt -destkeystore /tmp/kafka.${container}.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent + + if [ "${container}" == "clientrestproxy" ] + then + # used for other/rest-proxy-security-plugin test + # https://stackoverflow.com/a/8224863 + openssl pkcs12 -export -in /tmp/clientrestproxy-ca1-signed.crt -inkey /tmp/clientrestproxy.key \ + -out /tmp/clientrestproxy.p12 -name clientrestproxy \ + -CAfile /tmp/snakeoil-ca-1.crt -caname CARoot -passout pass:confluent $maybe_provider $maybe_nomac + + keytool -importkeystore \ + -deststorepass confluent -destkeypass confluent -destkeystore /tmp/kafka.restproxy.keystore.jks \ + -srckeystore /tmp/clientrestproxy.p12 -srcstoretype PKCS12 -srcstorepass confluent \ + -alias clientrestproxy + fi +done + From c4c5ca71777086841e36d676e77d12ad4c3533c2 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Dec 2024 13:47:31 +0100 Subject: [PATCH 083/659] removed --- .../security/certs-create.sh | 80 ---------------- environment/2way-ssl/security/certs-clean.sh | 9 -- environment/2way-ssl/security/certs-create.sh | 90 ------------------ environment/2way-ssl/security/certs-verify.sh | 14 --- environment/sasl-ssl/security/certs-clean.sh | 9 -- environment/sasl-ssl/security/certs-create.sh | 90 ------------------ environment/sasl-ssl/security/certs-verify.sh | 14 --- .../ssl_kerberos/security/certs-clean.sh | 9 -- .../ssl_kerberos/security/certs-create.sh | 91 ------------------- .../ssl_kerberos/security/certs-verify.sh | 14 --- .../kafka-connect-jsonata | 1 + .../security/certs-create.sh | 81 ----------------- 12 files changed, 1 insertion(+), 501 deletions(-) delete mode 100755 ccloud/fm-rabbitmq-source/security/certs-create.sh delete mode 100755 environment/2way-ssl/security/certs-clean.sh delete mode 100755 environment/2way-ssl/security/certs-create.sh delete mode 100755 environment/2way-ssl/security/certs-verify.sh delete mode 100755 environment/sasl-ssl/security/certs-clean.sh delete mode 100755 environment/sasl-ssl/security/certs-create.sh delete mode 100755 environment/sasl-ssl/security/certs-verify.sh delete mode 100755 environment/ssl_kerberos/security/certs-clean.sh delete mode 100755 environment/ssl_kerberos/security/certs-create.sh delete mode 100755 environment/ssl_kerberos/security/certs-verify.sh create mode 160000 other/kafka-connect-jsonata/kafka-connect-jsonata delete mode 100755 other/ldap-authorizer-with-ldap-failover/security/certs-create.sh diff --git a/ccloud/fm-rabbitmq-source/security/certs-create.sh b/ccloud/fm-rabbitmq-source/security/certs-create.sh deleted file mode 100755 index b89a52764d..0000000000 --- a/ccloud/fm-rabbitmq-source/security/certs-create.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in connect rabbitmq -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > ${i}_sslkey_creds - echo "confluent" > ${i}_keystore_creds - echo "confluent" > ${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent - - - # cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" - # keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent - -done diff --git a/environment/2way-ssl/security/certs-clean.sh b/environment/2way-ssl/security/certs-clean.sh deleted file mode 100755 index 92dedb388f..0000000000 --- a/environment/2way-ssl/security/certs-clean.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -set -o nounset \ - -o errexit \ - -o verbose -# -o xtrace - -# Cleanup files -rm -f *.crt *.csr *_creds *.jks *.srl *.key *.pem *.der *.p12 diff --git a/environment/2way-ssl/security/certs-create.sh b/environment/2way-ssl/security/certs-create.sh deleted file mode 100755 index a2948f8ed0..0000000000 --- a/environment/2way-ssl/security/certs-create.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in broker broker2 broker3 client schema-registry restproxy connect connect2 connect3 control-center clientrestproxy ksqldb-server conduktor -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > /tmp/${i}_sslkey_creds - echo "confluent" > /tmp/${i}_keystore_creds - echo "confluent" > /tmp/${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent - - - cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" - keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent -done - -# used for other/rest-proxy-security-plugin test -# https://stackoverflow.com/a/8224863 -openssl pkcs12 -export -in /tmp/clientrestproxy-ca1-signed.crt -inkey /tmp/clientrestproxy.key \ - -out /tmp/clientrestproxy.p12 -name clientrestproxy \ - -CAfile /tmp/snakeoil-ca-1.crt -caname CARoot -passout pass:confluent - -keytool -importkeystore \ - -deststorepass confluent -destkeypass confluent -destkeystore /tmp/kafka.restproxy.keystore.jks \ - -srckeystore /tmp/clientrestproxy.p12 -srcstoretype PKCS12 -srcstorepass confluent \ - -alias clientrestproxy diff --git a/environment/2way-ssl/security/certs-verify.sh b/environment/2way-ssl/security/certs-verify.sh deleted file mode 100755 index 2e6fe1b224..0000000000 --- a/environment/2way-ssl/security/certs-verify.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -set -o nounset \ - -o errexit \ - -o verbose - -# See what is in each keystore and truststore -for i in broker broker2 broker3 client schema-registry restproxy connect connect2 connect3 control-center clientrestproxy ksqldb-server -do - echo "------------------------------- $i keystore -------------------------------" - keytool -list -v -keystore /tmp/kafka.$i.keystore.jks -storepass confluent | grep -e Alias -e Entry - echo "------------------------------- $i truststore -------------------------------" - keytool -list -v -keystore /tmp/kafka.$i.truststore.jks -storepass confluent | grep -e Alias -e Entry -done diff --git a/environment/sasl-ssl/security/certs-clean.sh b/environment/sasl-ssl/security/certs-clean.sh deleted file mode 100755 index 92dedb388f..0000000000 --- a/environment/sasl-ssl/security/certs-clean.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -set -o nounset \ - -o errexit \ - -o verbose -# -o xtrace - -# Cleanup files -rm -f *.crt *.csr *_creds *.jks *.srl *.key *.pem *.der *.p12 diff --git a/environment/sasl-ssl/security/certs-create.sh b/environment/sasl-ssl/security/certs-create.sh deleted file mode 100755 index 0a16874028..0000000000 --- a/environment/sasl-ssl/security/certs-create.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent -provider base - -for i in broker broker2 broker3 client schema-registry restproxy connect connect2 connect3 control-center clientrestproxy ksqldb-server conduktor -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile -provider base - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > /tmp/${i}_sslkey_creds - echo "confluent" > /tmp/${i}_keystore_creds - echo "confluent" > /tmp/${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem -provider base - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent -provider base -nomacver - - - cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" - keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent -done - -# used for other/rest-proxy-security-plugin test -# https://stackoverflow.com/a/8224863 -openssl pkcs12 -export -in /tmp/clientrestproxy-ca1-signed.crt -inkey /tmp/clientrestproxy.key \ - -out /tmp/clientrestproxy.p12 -name clientrestproxy \ - -CAfile /tmp/snakeoil-ca-1.crt -caname CARoot -passout pass:confluent -provider base --nomac - -keytool -importkeystore \ - -deststorepass confluent -destkeypass confluent -destkeystore /tmp/kafka.restproxy.keystore.jks \ - -srckeystore /tmp/clientrestproxy.p12 -srcstoretype PKCS12 -srcstorepass confluent \ - -alias clientrestproxy diff --git a/environment/sasl-ssl/security/certs-verify.sh b/environment/sasl-ssl/security/certs-verify.sh deleted file mode 100755 index 2e6fe1b224..0000000000 --- a/environment/sasl-ssl/security/certs-verify.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -set -o nounset \ - -o errexit \ - -o verbose - -# See what is in each keystore and truststore -for i in broker broker2 broker3 client schema-registry restproxy connect connect2 connect3 control-center clientrestproxy ksqldb-server -do - echo "------------------------------- $i keystore -------------------------------" - keytool -list -v -keystore /tmp/kafka.$i.keystore.jks -storepass confluent | grep -e Alias -e Entry - echo "------------------------------- $i truststore -------------------------------" - keytool -list -v -keystore /tmp/kafka.$i.truststore.jks -storepass confluent | grep -e Alias -e Entry -done diff --git a/environment/ssl_kerberos/security/certs-clean.sh b/environment/ssl_kerberos/security/certs-clean.sh deleted file mode 100755 index 92dedb388f..0000000000 --- a/environment/ssl_kerberos/security/certs-clean.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -set -o nounset \ - -o errexit \ - -o verbose -# -o xtrace - -# Cleanup files -rm -f *.crt *.csr *_creds *.jks *.srl *.key *.pem *.der *.p12 diff --git a/environment/ssl_kerberos/security/certs-create.sh b/environment/ssl_kerberos/security/certs-create.sh deleted file mode 100755 index 97e68fbcb9..0000000000 --- a/environment/ssl_kerberos/security/certs-create.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in broker broker2 broker3 client schema-registry restproxy connect connect2 connect3 control-center clientrestproxy ksqldb-server -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost,dns:$i.kerberos-demo.local" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost,dns:$i.kerberos-demo.local" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -DNS.3 = $i.kerberos-demo.local -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost,dns:$i.kerberos-demo.local" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > /tmp/${i}_sslkey_creds - echo "confluent" > /tmp/${i}_keystore_creds - echo "confluent" > /tmp/${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent - - - cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" - keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent -done - -# used for other/rest-proxy-security-plugin test -# https://stackoverflow.com/a/8224863 -openssl pkcs12 -export -in /tmp/clientrestproxy-ca1-signed.crt -inkey /tmp/clientrestproxy.key \ - -out /tmp/clientrestproxy.p12 -name clientrestproxy \ - -CAfile /tmp/snakeoil-ca-1.crt -caname CARoot -passout pass:confluent - -keytool -importkeystore \ - -deststorepass confluent -destkeypass confluent -destkeystore /tmp/kafka.restproxy.keystore.jks \ - -srckeystore /tmp/clientrestproxy.p12 -srcstoretype PKCS12 -srcstorepass confluent \ - -alias clientrestproxy diff --git a/environment/ssl_kerberos/security/certs-verify.sh b/environment/ssl_kerberos/security/certs-verify.sh deleted file mode 100755 index 2e6fe1b224..0000000000 --- a/environment/ssl_kerberos/security/certs-verify.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -set -o nounset \ - -o errexit \ - -o verbose - -# See what is in each keystore and truststore -for i in broker broker2 broker3 client schema-registry restproxy connect connect2 connect3 control-center clientrestproxy ksqldb-server -do - echo "------------------------------- $i keystore -------------------------------" - keytool -list -v -keystore /tmp/kafka.$i.keystore.jks -storepass confluent | grep -e Alias -e Entry - echo "------------------------------- $i truststore -------------------------------" - keytool -list -v -keystore /tmp/kafka.$i.truststore.jks -storepass confluent | grep -e Alias -e Entry -done diff --git a/other/kafka-connect-jsonata/kafka-connect-jsonata b/other/kafka-connect-jsonata/kafka-connect-jsonata new file mode 160000 index 0000000000..e91eac7f61 --- /dev/null +++ b/other/kafka-connect-jsonata/kafka-connect-jsonata @@ -0,0 +1 @@ +Subproject commit e91eac7f6192d52b1db05457b4f16596eaa53351 diff --git a/other/ldap-authorizer-with-ldap-failover/security/certs-create.sh b/other/ldap-authorizer-with-ldap-failover/security/certs-create.sh deleted file mode 100755 index f76a83beec..0000000000 --- a/other/ldap-authorizer-with-ldap-failover/security/certs-create.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in broker ldap ldap2 ldap3 -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost,dns:$i.confluent.io" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost,dns:$i.confluent.io" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -DNS.3 = $i.confluent.io -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost,dns:$i.confluent.io" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > ${i}_sslkey_creds - echo "confluent" > ${i}_keystore_creds - echo "confluent" > ${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent - - - cacerts_path="$(readlink -f /usr/bin/java | sed "s:bin/java::")lib/security/cacerts" - keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore $cacerts_path -srcstorepass changeit -deststorepass confluent - -done From e8c59b9836ebcaa27c997a83e5f75b6fc7fabd9e Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Dec 2024 14:42:54 +0100 Subject: [PATCH 084/659] wip --- scripts/cli/playground | 8 +------- scripts/cli/src/bashly.yml | 1 - scripts/cli/src/commands/tools/certs-create.sh | 1 + 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index cbedeb2ea5..f34ef0d08d 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -18884,6 +18884,7 @@ playground_tools_certs_create_command() { then new_open_ssl=1 fi + mkdir -p "${output_folder}" cd "${output_folder}" cp $root_folder/scripts/cli/src/ssl/certs-create.sh . log "🔐 Generate keys and certificates in folder ${output_folder}" @@ -32486,13 +32487,6 @@ playground_tools_certs_create_parse_requirements() { # :command.default_assignments [[ -n ${args['--container']:-} ]] || args['--container']="broker broker2 broker3 client schema-registry restproxy connect connect2 connect3 control-center clientrestproxy ksqldb-server conduktor" - # :command.validations - # :flag.validations - if [[ -v args['--output-folder'] && -n $(validate_dir_exists "${args['--output-folder']:-}") ]]; then - printf "validation error in %s:\n%s\n" "--output-folder FOLDER" "$(validate_dir_exists "${args['--output-folder']:-}")" >&2 - exit 1 - fi - } # :command.parse_requirements diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index bfb257c7ca..52e9ba10c1 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -1610,7 +1610,6 @@ commands: - *verbose - long: --output-folder required: true - validate: dir_exists arg: folder help: |- 📁 Folder where certificates are created diff --git a/scripts/cli/src/commands/tools/certs-create.sh b/scripts/cli/src/commands/tools/certs-create.sh index c0d7ed4c89..74623e2ed0 100644 --- a/scripts/cli/src/commands/tools/certs-create.sh +++ b/scripts/cli/src/commands/tools/certs-create.sh @@ -22,6 +22,7 @@ if version_gt $CONNECT_TAG "7.7.99" then new_open_ssl=1 fi +mkdir -p "${output_folder}" cd "${output_folder}" cp $root_folder/scripts/cli/src/ssl/certs-create.sh . log "🔐 Generate keys and certificates in folder ${output_folder}" From 2c18f8f4e3c2272b0cd23148901e4f945395cc03 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Dec 2024 16:02:46 +0100 Subject: [PATCH 085/659] wip --- connect/connect-ftps-sink/ftps-sink.sh | 8 +- .../connect-ftps-sink/security/certs-clean.sh | 9 --- .../security/certs-create.sh | 78 ------------------- .../security/certs-verify.sh | 14 ---- .../connect-ftps-sink/security/kafkajks.txt | 1 - connect/connect-ftps-source/ftps-source.sh | 9 +-- .../security/certs-clean.sh | 9 --- .../security/certs-create.sh | 78 ------------------- .../security/certs-verify.sh | 14 ---- 9 files changed, 8 insertions(+), 212 deletions(-) delete mode 100755 connect/connect-ftps-sink/security/certs-clean.sh delete mode 100755 connect/connect-ftps-sink/security/certs-create.sh delete mode 100755 connect/connect-ftps-sink/security/certs-verify.sh delete mode 100644 connect/connect-ftps-sink/security/kafkajks.txt delete mode 100755 connect/connect-ftps-source/security/certs-clean.sh delete mode 100755 connect/connect-ftps-source/security/certs-create.sh delete mode 100755 connect/connect-ftps-source/security/certs-verify.sh diff --git a/connect/connect-ftps-sink/ftps-sink.sh b/connect/connect-ftps-sink/ftps-sink.sh index df61775957..d80082214a 100755 --- a/connect/connect-ftps-sink/ftps-sink.sh +++ b/connect/connect-ftps-sink/ftps-sink.sh @@ -4,10 +4,10 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -cd ${DIR}/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/" -cd ${DIR} +cd ../../connect/connect-ftps-sink/security +playground tools certs-create --output-folder "$PWD" --container ftps-server +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout /tmp/vsftpd.pem -out /tmp/vsftpd.pem -config /tmp/cert_config -reqexts 'my server exts' +cd - if [[ "$(uname)" != "Darwin" ]] then diff --git a/connect/connect-ftps-sink/security/certs-clean.sh b/connect/connect-ftps-sink/security/certs-clean.sh deleted file mode 100755 index 92dedb388f..0000000000 --- a/connect/connect-ftps-sink/security/certs-clean.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -set -o nounset \ - -o errexit \ - -o verbose -# -o xtrace - -# Cleanup files -rm -f *.crt *.csr *_creds *.jks *.srl *.key *.pem *.der *.p12 diff --git a/connect/connect-ftps-sink/security/certs-create.sh b/connect/connect-ftps-sink/security/certs-create.sh deleted file mode 100755 index 779d66b4fa..0000000000 --- a/connect/connect-ftps-sink/security/certs-create.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout /tmp/vsftpd.pem -out /tmp/vsftpd.pem -config /tmp/cert_config -reqexts 'my server exts' - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in ftps-server -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > ${i}_sslkey_creds - echo "confluent" > ${i}_keystore_creds - echo "confluent" > ${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent - -done diff --git a/connect/connect-ftps-sink/security/certs-verify.sh b/connect/connect-ftps-sink/security/certs-verify.sh deleted file mode 100755 index 51dd6ae5bd..0000000000 --- a/connect/connect-ftps-sink/security/certs-verify.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -set -o nounset \ - -o errexit \ - -o verbose - -# See what is in each keystore and truststore -for i in ftps-server connnect -do - echo "------------------------------- $i keystore -------------------------------" - keytool -list -v -keystore /tmp/kafka.$i.keystore.jks -storepass confluent | grep -e Alias -e Entry - echo "------------------------------- $i truststore -------------------------------" - keytool -list -v -keystore /tmp/kafka.$i.truststore.jks -storepass confluent | grep -e Alias -e Entry -done diff --git a/connect/connect-ftps-sink/security/kafkajks.txt b/connect/connect-ftps-sink/security/kafkajks.txt deleted file mode 100644 index 39dd410e61..0000000000 --- a/connect/connect-ftps-sink/security/kafkajks.txt +++ /dev/null @@ -1 +0,0 @@ -password=confluent \ No newline at end of file diff --git a/connect/connect-ftps-source/ftps-source.sh b/connect/connect-ftps-source/ftps-source.sh index e4b4b58477..db7734e826 100755 --- a/connect/connect-ftps-source/ftps-source.sh +++ b/connect/connect-ftps-source/ftps-source.sh @@ -4,11 +4,10 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -cd ${DIR}/security -log "🔐 Generate keys and certificates used for SSL" -docker run -u0 --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/" -cd ${DIR} - +cd ../../connect/connect-ftps-source/security +playground tools certs-create --output-folder "$PWD" --container ftps-server +docker run --quiet --rm -v $PWD:/tmp alpine/openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout /tmp/vsftpd.pem -out /tmp/vsftpd.pem -config /tmp/cert_config -reqexts 'my server exts' +cd - if [[ "$(uname)" != "Darwin" ]] then diff --git a/connect/connect-ftps-source/security/certs-clean.sh b/connect/connect-ftps-source/security/certs-clean.sh deleted file mode 100755 index 92dedb388f..0000000000 --- a/connect/connect-ftps-source/security/certs-clean.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -set -o nounset \ - -o errexit \ - -o verbose -# -o xtrace - -# Cleanup files -rm -f *.crt *.csr *_creds *.jks *.srl *.key *.pem *.der *.p12 diff --git a/connect/connect-ftps-source/security/certs-create.sh b/connect/connect-ftps-source/security/certs-create.sh deleted file mode 100755 index 779d66b4fa..0000000000 --- a/connect/connect-ftps-source/security/certs-create.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/bash - -#set -o nounset \ -# -o errexit \ -# -o verbose \ -# -o xtrace - -# Cleanup files -rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile - -openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout /tmp/vsftpd.pem -out /tmp/vsftpd.pem -config /tmp/cert_config -reqexts 'my server exts' - -# Generate CA key -openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent - -for i in ftps-server -do - echo "------------------------------- $i -------------------------------" - - # Create host keystore - keytool -genkey -noprompt \ - -alias $i \ - -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:$i,dns:localhost" \ - -keystore /tmp/kafka.$i.keystore.jks \ - -keyalg RSA \ - -storepass confluent \ - -keypass confluent \ - -storetype pkcs12 - - # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #openssl req -in $i.csr -text -noout - -cat << EOF > /tmp/extfile -[req] -distinguished_name = req_distinguished_name -x509_extensions = v3_req -prompt = no -[req_distinguished_name] -CN = $i -[v3_req] -subjectAltName = @alt_names -[alt_names] -DNS.1 = $i -DNS.2 = localhost -EOF - # Sign the host certificate with the certificate authority (CA) - openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile - - #openssl x509 -noout -text -in $i-ca1-signed.crt - - # Sign and import the CA cert into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" - #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent - - # Create truststore and import the CA cert - keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent - - # Save creds - echo "confluent" > ${i}_sslkey_creds - echo "confluent" > ${i}_keystore_creds - echo "confluent" > ${i}_truststore_creds - - # Create pem files and keys used for Schema Registry HTTPS testing - # openssl x509 -noout -modulus -in client.certificate.pem | openssl md5 - # openssl rsa -noout -modulus -in client.key | openssl md5 - # log "GET /" | openssl s_client -connect localhost:8081/subjects -cert client.certificate.pem -key client.key -tls1 - keytool -export -alias $i -file /tmp/$i.der -keystore /tmp/kafka.$i.keystore.jks -storepass confluent - openssl x509 -inform der -in /tmp/$i.der -out /tmp/$i.certificate.pem - keytool -importkeystore -srckeystore /tmp/kafka.$i.keystore.jks -destkeystore /tmp/$i.keystore.p12 -deststoretype PKCS12 -deststorepass confluent -srcstorepass confluent -noprompt - openssl pkcs12 -in /tmp/$i.keystore.p12 -nodes -nocerts -out /tmp/$i.key -passin pass:confluent - -done diff --git a/connect/connect-ftps-source/security/certs-verify.sh b/connect/connect-ftps-source/security/certs-verify.sh deleted file mode 100755 index 61e9f48ba4..0000000000 --- a/connect/connect-ftps-source/security/certs-verify.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -set -o nounset \ - -o errexit \ - -o verbose - -# See what is in each keystore and truststore -for i in ftps-server connnect -do - echo "------------------------------- $i keystore -------------------------------" - keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent | grep -e Alias -e Entry - echo "------------------------------- $i truststore -------------------------------" - keytool -list -v -keystore kafka.$i.truststore.jks -storepass confluent | grep -e Alias -e Entry -done From e17cda0610b12c2c64240e9b4786825f4b887ec3 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 9 Dec 2024 17:05:19 +0100 Subject: [PATCH 086/659] mkdir --- ccloud/fm-mqtt-source/fully-managed-mqtt-source-mtls.sh | 1 + ccloud/fm-rabbitmq-sink/fully-managed-rabbitmq-sink-ssl.sh | 1 + ccloud/fm-rabbitmq-source/fully-managed-rabbitmq-source-ssl.sh | 1 + ccloud/rest-proxy-security-plugin/start.sh | 1 + connect/connect-active-mq-sink/active-mq-sink-mtls.sh | 1 + connect/connect-ibm-mq-sink/ibm-mq-sink-mtls.sh | 1 + connect/connect-ibm-mq-sink/ibm-mq-sink-ssl.sh | 1 + connect/connect-ibm-mq-source/ibm-mq-mtls.sh | 1 + connect/connect-ibm-mq-source/ibm-mq-ssl.sh | 1 + connect/connect-mqtt-sink/mqtt-sink-mtls.sh | 1 + connect/connect-mqtt-source/mqtt-source-mtls.sh | 1 + connect/connect-rabbitmq-sink/rabbitmq-sink-ssl.sh | 1 + connect/connect-rabbitmq-source/rabbitmq-source-ssl.sh | 1 + 13 files changed, 13 insertions(+) diff --git a/ccloud/fm-mqtt-source/fully-managed-mqtt-source-mtls.sh b/ccloud/fm-mqtt-source/fully-managed-mqtt-source-mtls.sh index 78c5634d50..ce859b7aa3 100755 --- a/ccloud/fm-mqtt-source/fully-managed-mqtt-source-mtls.sh +++ b/ccloud/fm-mqtt-source/fully-managed-mqtt-source-mtls.sh @@ -4,6 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh +mkdir -p ../../ccloud/fm-mqtt-source/security cd ../../ccloud/fm-mqtt-source/security playground tools certs-create --output-folder "$PWD" --container connect --container mosquitto --verbose base64_truststore=$(cat $PWD/kafka.connect.truststore.jks | base64 | tr -d '\n') diff --git a/ccloud/fm-rabbitmq-sink/fully-managed-rabbitmq-sink-ssl.sh b/ccloud/fm-rabbitmq-sink/fully-managed-rabbitmq-sink-ssl.sh index 6f20bf3b80..e85c651c1d 100755 --- a/ccloud/fm-rabbitmq-sink/fully-managed-rabbitmq-sink-ssl.sh +++ b/ccloud/fm-rabbitmq-sink/fully-managed-rabbitmq-sink-ssl.sh @@ -5,6 +5,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh NGROK_AUTH_TOKEN=${NGROK_AUTH_TOKEN:-$1} +mkdir -p ../../ccloud/fm-rabbitmq-sink/security cd ../../ccloud/fm-rabbitmq-sink/security playground tools certs-create --output-folder "$PWD" --container connect --container rabbitmq base64_truststore=$(cat $PWD/kafka.connect.truststore.jks | base64 | tr -d '\n') diff --git a/ccloud/fm-rabbitmq-source/fully-managed-rabbitmq-source-ssl.sh b/ccloud/fm-rabbitmq-source/fully-managed-rabbitmq-source-ssl.sh index 6c22fd6f8f..ad50baa658 100755 --- a/ccloud/fm-rabbitmq-source/fully-managed-rabbitmq-source-ssl.sh +++ b/ccloud/fm-rabbitmq-source/fully-managed-rabbitmq-source-ssl.sh @@ -4,6 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh +mkdir -p ../../ccloud/fm-rabbitmq-source/security cd ../../ccloud/fm-rabbitmq-source/security playground tools certs-create --output-folder "$PWD" --container connect --container rabbitmq base64_truststore=$(cat $PWD/kafka.connect.truststore.jks | base64 | tr -d '\n') diff --git a/ccloud/rest-proxy-security-plugin/start.sh b/ccloud/rest-proxy-security-plugin/start.sh index 39cb43efe8..b0b584e2dc 100755 --- a/ccloud/rest-proxy-security-plugin/start.sh +++ b/ccloud/rest-proxy-security-plugin/start.sh @@ -32,6 +32,7 @@ sed -e "s|:CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_KEY:|$CCLOUD_REST_PROXY_SECURIT -e "s|:CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_SECRET:|$CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_SECRET|g" \ ../../ccloud/rest-proxy-security-plugin/kafka-rest.jaas-template.conf > ../../ccloud/rest-proxy-security-plugin/kafka-rest.jaas.conf +mkdir -p ../../ccloud/rest-proxy-security-plugin/security cd ../../ccloud/rest-proxy-security-plugin/security playground tools certs-create --output-folder "$PWD" --container restproxy --container $CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_KEY --verbose cd - diff --git a/connect/connect-active-mq-sink/active-mq-sink-mtls.sh b/connect/connect-active-mq-sink/active-mq-sink-mtls.sh index cf9a414df1..5505063729 100755 --- a/connect/connect-active-mq-sink/active-mq-sink-mtls.sh +++ b/connect/connect-active-mq-sink/active-mq-sink-mtls.sh @@ -4,6 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh +mkdir -p ../../connect/connect-active-mq-sink/security cd ../../connect/connect-active-mq-sink/security playground tools certs-create --output-folder "$PWD" --container connect --container activemq cd - diff --git a/connect/connect-ibm-mq-sink/ibm-mq-sink-mtls.sh b/connect/connect-ibm-mq-sink/ibm-mq-sink-mtls.sh index 7402443c3a..503dd3c506 100755 --- a/connect/connect-ibm-mq-sink/ibm-mq-sink-mtls.sh +++ b/connect/connect-ibm-mq-sink/ibm-mq-sink-mtls.sh @@ -31,6 +31,7 @@ then fi cd - +mkdir -p ../../connect/connect-ibm-mq-sink/security cd ../../connect/connect-ibm-mq-sink/security playground tools certs-create --output-folder "$PWD" --container connect --container ibmmq cd - diff --git a/connect/connect-ibm-mq-sink/ibm-mq-sink-ssl.sh b/connect/connect-ibm-mq-sink/ibm-mq-sink-ssl.sh index c04379eefb..9173a974ef 100755 --- a/connect/connect-ibm-mq-sink/ibm-mq-sink-ssl.sh +++ b/connect/connect-ibm-mq-sink/ibm-mq-sink-ssl.sh @@ -31,6 +31,7 @@ then fi cd - +mkdir -p ../../connect/connect-ibm-mq-sink/security cd ../../connect/connect-ibm-mq-sink/security playground tools certs-create --output-folder "$PWD" --container connect --container ibmmq cd - diff --git a/connect/connect-ibm-mq-source/ibm-mq-mtls.sh b/connect/connect-ibm-mq-source/ibm-mq-mtls.sh index cd58f50756..f1bb9a36df 100755 --- a/connect/connect-ibm-mq-source/ibm-mq-mtls.sh +++ b/connect/connect-ibm-mq-source/ibm-mq-mtls.sh @@ -31,6 +31,7 @@ then fi cd - +mkdir -p ../../connect/connect-ibm-mq-source/security cd ../../connect/connect-ibm-mq-source/security playground tools certs-create --output-folder "$PWD" --container connect --container ibmmq cd - diff --git a/connect/connect-ibm-mq-source/ibm-mq-ssl.sh b/connect/connect-ibm-mq-source/ibm-mq-ssl.sh index aea02b60ab..27d8d68c4e 100755 --- a/connect/connect-ibm-mq-source/ibm-mq-ssl.sh +++ b/connect/connect-ibm-mq-source/ibm-mq-ssl.sh @@ -31,6 +31,7 @@ then fi cd - +mkdir -p ../../connect/connect-ibm-mq-source/security cd ../../connect/connect-ibm-mq-source/security playground tools certs-create --output-folder "$PWD" --container connect --container ibmmq cd - diff --git a/connect/connect-mqtt-sink/mqtt-sink-mtls.sh b/connect/connect-mqtt-sink/mqtt-sink-mtls.sh index 6efa9a6459..8345527f66 100755 --- a/connect/connect-mqtt-sink/mqtt-sink-mtls.sh +++ b/connect/connect-mqtt-sink/mqtt-sink-mtls.sh @@ -4,6 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh +mkdir -p ../../connect/connect-mqtt-sink/security cd ../../connect/connect-mqtt-sink/security playground tools certs-create --output-folder "$PWD" --container connect --container mosquitto cd - diff --git a/connect/connect-mqtt-source/mqtt-source-mtls.sh b/connect/connect-mqtt-source/mqtt-source-mtls.sh index 8b8c114ffc..7b014f2d06 100755 --- a/connect/connect-mqtt-source/mqtt-source-mtls.sh +++ b/connect/connect-mqtt-source/mqtt-source-mtls.sh @@ -5,6 +5,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh +mkdir -p ../../connect/connect-mqtt-source/security cd ../../connect/connect-mqtt-source/security playground tools certs-create --output-folder "$PWD" --container connect --container mosquitto cd - diff --git a/connect/connect-rabbitmq-sink/rabbitmq-sink-ssl.sh b/connect/connect-rabbitmq-sink/rabbitmq-sink-ssl.sh index 05f9fff08b..2e790ac9c3 100755 --- a/connect/connect-rabbitmq-sink/rabbitmq-sink-ssl.sh +++ b/connect/connect-rabbitmq-sink/rabbitmq-sink-ssl.sh @@ -4,6 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh +mkdir -p ../../connect/connect-rabbitmq-sink/security cd ../../connect/connect-rabbitmq-sink/security playground tools certs-create --output-folder "$PWD" --container connect --container rabbitmq cd - diff --git a/connect/connect-rabbitmq-source/rabbitmq-source-ssl.sh b/connect/connect-rabbitmq-source/rabbitmq-source-ssl.sh index 642c42fc71..90db1df75c 100755 --- a/connect/connect-rabbitmq-source/rabbitmq-source-ssl.sh +++ b/connect/connect-rabbitmq-source/rabbitmq-source-ssl.sh @@ -4,6 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh +mkdir -p ../../connect/connect-rabbitmq-source/security cd ../../connect/connect-rabbitmq-source/security playground tools certs-create --output-folder "$PWD" --container connect --container rabbitmq cd - From 1ce09245b31630f6286e0c753ae6ca0188b7adce Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 10 Dec 2024 10:33:10 +0100 Subject: [PATCH 087/659] fix --- scripts/cli/src/ssl/certs-create.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/cli/src/ssl/certs-create.sh b/scripts/cli/src/ssl/certs-create.sh index a2f1733515..e8cfb9e1dd 100755 --- a/scripts/cli/src/ssl/certs-create.sh +++ b/scripts/cli/src/ssl/certs-create.sh @@ -64,9 +64,9 @@ EOF keytool -noprompt -keystore /tmp/kafka.${container}.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent # Save creds - echo "confluent" > /tmp/${i}_sslkey_creds - echo "confluent" > /tmp/${i}_keystore_creds - echo "confluent" > /tmp/${i}_truststore_creds + echo "confluent" > /tmp/${container}_sslkey_creds + echo "confluent" > /tmp/${container}_keystore_creds + echo "confluent" > /tmp/${container}_truststore_creds # Create pem files and keys used for Schema Registry HTTPS testing keytool -export -alias ${container} -file /tmp/${container}.der -keystore /tmp/kafka.${container}.keystore.jks -storepass confluent From d7924322efe046d96e669649483f4ea1785c7f21 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 10 Dec 2024 11:02:08 +0100 Subject: [PATCH 088/659] perm fix --- .../fully-managed-mysql-source-ssl.sh | 10 ++++++++++ connect/connect-jdbc-mysql-sink/mysql-sink-mtls.sh | 10 ++++++++++ connect/connect-jdbc-mysql-sink/mysql-sink-ssl.sh | 10 ++++++++++ connect/connect-jdbc-mysql-source/mysql-mtls.sh | 10 ++++++++++ connect/connect-jdbc-mysql-source/mysql-ssl.sh | 10 ++++++++++ 5 files changed, 50 insertions(+) diff --git a/ccloud/fm-jdbc-mysql-source/fully-managed-mysql-source-ssl.sh b/ccloud/fm-jdbc-mysql-source/fully-managed-mysql-source-ssl.sh index 41503987fc..7e60c05a47 100755 --- a/ccloud/fm-jdbc-mysql-source/fully-managed-mysql-source-ssl.sh +++ b/ccloud/fm-jdbc-mysql-source/fully-managed-mysql-source-ssl.sh @@ -47,6 +47,16 @@ fi docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword # Convert the client key and certificate files to a PKCS #12 archive docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 +if [[ "$OSTYPE" == "darwin"* ]] +then + # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 + chmod -R a+rw . +else + # on CI, docker is run as runneradmin user, need to use sudo + ls -lrt + sudo chmod -R a+rw . + ls -lrt +fi # Import the client key and certificate into a Java keystore: docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword cd - diff --git a/connect/connect-jdbc-mysql-sink/mysql-sink-mtls.sh b/connect/connect-jdbc-mysql-sink/mysql-sink-mtls.sh index 5122162aba..2c516d8407 100755 --- a/connect/connect-jdbc-mysql-sink/mysql-sink-mtls.sh +++ b/connect/connect-jdbc-mysql-sink/mysql-sink-mtls.sh @@ -45,6 +45,16 @@ fi docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword # Convert the client key and certificate files to a PKCS #12 archive docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 +if [[ "$OSTYPE" == "darwin"* ]] +then + # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 + chmod -R a+rw . +else + # on CI, docker is run as runneradmin user, need to use sudo + ls -lrt + sudo chmod -R a+rw . + ls -lrt +fi # Import the client key and certificate into a Java keystore: docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword cd - diff --git a/connect/connect-jdbc-mysql-sink/mysql-sink-ssl.sh b/connect/connect-jdbc-mysql-sink/mysql-sink-ssl.sh index 768445d245..337ff4054b 100755 --- a/connect/connect-jdbc-mysql-sink/mysql-sink-ssl.sh +++ b/connect/connect-jdbc-mysql-sink/mysql-sink-ssl.sh @@ -45,6 +45,16 @@ fi docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword # Convert the client key and certificate files to a PKCS #12 archive docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 +if [[ "$OSTYPE" == "darwin"* ]] +then + # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 + chmod -R a+rw . +else + # on CI, docker is run as runneradmin user, need to use sudo + ls -lrt + sudo chmod -R a+rw . + ls -lrt +fi # Import the client key and certificate into a Java keystore: docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword cd - diff --git a/connect/connect-jdbc-mysql-source/mysql-mtls.sh b/connect/connect-jdbc-mysql-source/mysql-mtls.sh index e2536ddb19..04f6981e22 100755 --- a/connect/connect-jdbc-mysql-source/mysql-mtls.sh +++ b/connect/connect-jdbc-mysql-source/mysql-mtls.sh @@ -45,6 +45,16 @@ fi docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword # Convert the client key and certificate files to a PKCS #12 archive docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 +if [[ "$OSTYPE" == "darwin"* ]] +then + # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 + chmod -R a+rw . +else + # on CI, docker is run as runneradmin user, need to use sudo + ls -lrt + sudo chmod -R a+rw . + ls -lrt +fi # Import the client key and certificate into a Java keystore: docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword cd - diff --git a/connect/connect-jdbc-mysql-source/mysql-ssl.sh b/connect/connect-jdbc-mysql-source/mysql-ssl.sh index c1022a4b2f..4abbd27561 100755 --- a/connect/connect-jdbc-mysql-source/mysql-ssl.sh +++ b/connect/connect-jdbc-mysql-source/mysql-ssl.sh @@ -44,6 +44,16 @@ fi docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword # Convert the client key and certificate files to a PKCS #12 archive docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 +if [[ "$OSTYPE" == "darwin"* ]] +then + # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 + chmod -R a+rw . +else + # on CI, docker is run as runneradmin user, need to use sudo + ls -lrt + sudo chmod -R a+rw . + ls -lrt +fi # Import the client key and certificate into a Java keystore: docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword cd - From 709537e0b9efe6144a800968ed32e4ecd1095375 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 10 Dec 2024 11:12:26 +0100 Subject: [PATCH 089/659] add cli to PATH --- .github/workflows/ci-environments.yml | 8 ++++++-- .github/workflows/ci-self-managed.yml | 4 +++- .github/workflows/ci.yml | 8 ++++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-environments.yml b/.github/workflows/ci-environments.yml index 523190de89..0f5cfeb473 100644 --- a/.github/workflows/ci-environments.yml +++ b/.github/workflows/ci-environments.yml @@ -111,7 +111,9 @@ jobs: DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD}} - name: Build and Test - run: bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" "${{ matrix.environment }}" + run: | + echo "$GITHUB_WORKSPACE/scripts/cli" >> $GITHUB_PATH + bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" "${{ matrix.environment }}" env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} @@ -294,7 +296,9 @@ jobs: DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD}} - name: Build and Test - run: bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" "${{ matrix.environment }}" + run: | + echo "$GITHUB_WORKSPACE/scripts/cli" >> $GITHUB_PATH + bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" "${{ matrix.environment }}" env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} diff --git a/.github/workflows/ci-self-managed.yml b/.github/workflows/ci-self-managed.yml index 52f84b0519..cc10ea8522 100644 --- a/.github/workflows/ci-self-managed.yml +++ b/.github/workflows/ci-self-managed.yml @@ -85,7 +85,9 @@ jobs: export PATH=$PATH:/usr/local/bin - name: Build and Test - run: bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" + run: | + echo "$GITHUB_WORKSPACE/scripts/cli" >> $GITHUB_PATH + bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b1ec34a9b..d3599a0879 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -223,7 +223,9 @@ jobs: DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD}} - name: Build and Test - run: bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" + run: | + echo "$GITHUB_WORKSPACE/scripts/cli" >> $GITHUB_PATH + bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} @@ -411,7 +413,9 @@ jobs: DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD}} - name: Build and Test - run: bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" + run: | + echo "$GITHUB_WORKSPACE/scripts/cli" >> $GITHUB_PATH + bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} From 64006accf842650301966b57a2113c677bb3f0b2 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 10 Dec 2024 11:18:24 +0100 Subject: [PATCH 090/659] PATH --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d3599a0879..a2b6c290b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -224,7 +224,7 @@ jobs: - name: Build and Test run: | - echo "$GITHUB_WORKSPACE/scripts/cli" >> $GITHUB_PATH + export PATH=$PATH:$GITHUB_WORKSPACE/scripts/cli bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} @@ -414,7 +414,7 @@ jobs: - name: Build and Test run: | - echo "$GITHUB_WORKSPACE/scripts/cli" >> $GITHUB_PATH + export PATH=$PATH:$GITHUB_WORKSPACE/scripts/cli bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} From c28cb984dc10e6ad978d5b94e7632253ad9b254a Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 10 Dec 2024 11:23:41 +0100 Subject: [PATCH 091/659] PATH --- .github/workflows/ci-environments.yml | 4 ++-- .github/workflows/ci-self-managed.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-environments.yml b/.github/workflows/ci-environments.yml index 0f5cfeb473..af1e255269 100644 --- a/.github/workflows/ci-environments.yml +++ b/.github/workflows/ci-environments.yml @@ -112,7 +112,7 @@ jobs: - name: Build and Test run: | - echo "$GITHUB_WORKSPACE/scripts/cli" >> $GITHUB_PATH + export PATH=$PATH:$GITHUB_WORKSPACE/scripts/cli bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" "${{ matrix.environment }}" env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} @@ -297,7 +297,7 @@ jobs: - name: Build and Test run: | - echo "$GITHUB_WORKSPACE/scripts/cli" >> $GITHUB_PATH + export PATH=$PATH:$GITHUB_WORKSPACE/scripts/cli bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" "${{ matrix.environment }}" env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} diff --git a/.github/workflows/ci-self-managed.yml b/.github/workflows/ci-self-managed.yml index cc10ea8522..0915c6ac87 100644 --- a/.github/workflows/ci-self-managed.yml +++ b/.github/workflows/ci-self-managed.yml @@ -86,7 +86,7 @@ jobs: - name: Build and Test run: | - echo "$GITHUB_WORKSPACE/scripts/cli" >> $GITHUB_PATH + export PATH=$PATH:$GITHUB_WORKSPACE/scripts/cli bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} From 79ef013f634fdaff800cd305b33649191e139aa8 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 10 Dec 2024 11:28:42 +0100 Subject: [PATCH 092/659] removed --- other/kafka-connect-jsonata/kafka-connect-jsonata | 1 - 1 file changed, 1 deletion(-) delete mode 160000 other/kafka-connect-jsonata/kafka-connect-jsonata diff --git a/other/kafka-connect-jsonata/kafka-connect-jsonata b/other/kafka-connect-jsonata/kafka-connect-jsonata deleted file mode 160000 index e91eac7f61..0000000000 --- a/other/kafka-connect-jsonata/kafka-connect-jsonata +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e91eac7f6192d52b1db05457b4f16596eaa53351 From bd96b2061bb34bdb7fa1103532adb9cd35075a8c Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 10 Dec 2024 14:59:41 +0100 Subject: [PATCH 093/659] fix --- .../active-mq-sink-mtls.sh | 4 +- .../security/certs-create.sh | 68 +++++++++++++++++++ .../active-mq-source-mtls.sh | 4 +- .../security/certs-create.sh | 68 +++++++++++++++++++ 4 files changed, 140 insertions(+), 4 deletions(-) create mode 100755 connect/connect-active-mq-sink/security/certs-create.sh create mode 100755 connect/connect-active-mq-source/security/certs-create.sh diff --git a/connect/connect-active-mq-sink/active-mq-sink-mtls.sh b/connect/connect-active-mq-sink/active-mq-sink-mtls.sh index 5505063729..adae23902c 100755 --- a/connect/connect-active-mq-sink/active-mq-sink-mtls.sh +++ b/connect/connect-active-mq-sink/active-mq-sink-mtls.sh @@ -4,9 +4,9 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -mkdir -p ../../connect/connect-active-mq-sink/security cd ../../connect/connect-active-mq-sink/security -playground tools certs-create --output-folder "$PWD" --container connect --container activemq +log "🔐 Generate keys and certificates used for SSL using rmohr/activemq:5.15.9 image" +docker run -u0 --rm -v $PWD:/tmp rmohr/activemq:5.15.9 bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/" cd - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} diff --git a/connect/connect-active-mq-sink/security/certs-create.sh b/connect/connect-active-mq-sink/security/certs-create.sh new file mode 100755 index 0000000000..2df14f3852 --- /dev/null +++ b/connect/connect-active-mq-sink/security/certs-create.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +#set -o nounset \ +# -o errexit \ +# -o verbose \ +# -o xtrace + +# Cleanup files +rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile + +# Generate CA key +openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent + +for i in connect activemq +do + echo "------------------------------- $i -------------------------------" + + # Create host keystore + keytool -genkey -noprompt \ + -alias $i \ + -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ + -ext "SAN=dns:$i,dns:localhost" \ + -keystore /tmp/kafka.$i.keystore.jks \ + -keyalg RSA \ + -storepass confluent \ + -keypass confluent \ + -storetype pkcs12 + + # Create the certificate signing request (CSR) + keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" + #openssl req -in $i.csr -text -noout + +cat << EOF > /tmp/extfile +[req] +distinguished_name = req_distinguished_name +x509_extensions = v3_req +prompt = no +[req_distinguished_name] +CN = $i +[v3_req] +subjectAltName = @alt_names +[alt_names] +DNS.1 = $i +DNS.2 = localhost +EOF + # Sign the host certificate with the certificate authority (CA) + openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile + + #openssl x509 -noout -text -in $i-ca1-signed.crt + + # Sign and import the CA cert into the keystore + keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent + #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent + + # Sign and import the host certificate into the keystore + keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" + #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent + + # Create truststore and import the CA cert + keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent + + # Save creds + echo "confluent" > /tmp/${i}_sslkey_creds + echo "confluent" > /tmp/${i}_keystore_creds + echo "confluent" > /tmp/${i}_truststore_creds + + keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore "/usr/local/openjdk-8/lib/security/cacerts" -srcstorepass changeit -deststorepass confluent +done \ No newline at end of file diff --git a/connect/connect-active-mq-source/active-mq-source-mtls.sh b/connect/connect-active-mq-source/active-mq-source-mtls.sh index 6e2ea72a01..4f7e4c47b5 100755 --- a/connect/connect-active-mq-source/active-mq-source-mtls.sh +++ b/connect/connect-active-mq-source/active-mq-source-mtls.sh @@ -4,10 +4,10 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -cd ${DIR}/security +cd ../../connect/connect-active-mq-source/security log "🔐 Generate keys and certificates used for SSL using rmohr/activemq:5.15.9 image" docker run -u0 --rm -v $PWD:/tmp rmohr/activemq:5.15.9 bash -c "/tmp/certs-create.sh > /dev/null 2>&1 && chown -R $(id -u $USER):$(id -g $USER) /tmp/" -cd ${DIR} +cd - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.mtls.yml" diff --git a/connect/connect-active-mq-source/security/certs-create.sh b/connect/connect-active-mq-source/security/certs-create.sh new file mode 100755 index 0000000000..2df14f3852 --- /dev/null +++ b/connect/connect-active-mq-source/security/certs-create.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +#set -o nounset \ +# -o errexit \ +# -o verbose \ +# -o xtrace + +# Cleanup files +rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile + +# Generate CA key +openssl req -new -x509 -keyout /tmp/snakeoil-ca-1.key -out /tmp/snakeoil-ca-1.crt -days 365 -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/ST=Ca/C=US' -passin pass:confluent -passout pass:confluent + +for i in connect activemq +do + echo "------------------------------- $i -------------------------------" + + # Create host keystore + keytool -genkey -noprompt \ + -alias $i \ + -dname "CN=$i,OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ + -ext "SAN=dns:$i,dns:localhost" \ + -keystore /tmp/kafka.$i.keystore.jks \ + -keyalg RSA \ + -storepass confluent \ + -keypass confluent \ + -storetype pkcs12 + + # Create the certificate signing request (CSR) + keytool -keystore /tmp/kafka.$i.keystore.jks -alias $i -certreq -file /tmp/$i.csr -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" + #openssl req -in $i.csr -text -noout + +cat << EOF > /tmp/extfile +[req] +distinguished_name = req_distinguished_name +x509_extensions = v3_req +prompt = no +[req_distinguished_name] +CN = $i +[v3_req] +subjectAltName = @alt_names +[alt_names] +DNS.1 = $i +DNS.2 = localhost +EOF + # Sign the host certificate with the certificate authority (CA) + openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/$i.csr -out /tmp/$i-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile + + #openssl x509 -noout -text -in $i-ca1-signed.crt + + # Sign and import the CA cert into the keystore + keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent + #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent + + # Sign and import the host certificate into the keystore + keytool -noprompt -keystore /tmp/kafka.$i.keystore.jks -alias $i -import -file /tmp/$i-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:$i,dns:localhost" + #keytool -list -v -keystore kafka.$i.keystore.jks -storepass confluent + + # Create truststore and import the CA cert + keytool -noprompt -keystore /tmp/kafka.$i.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent + + # Save creds + echo "confluent" > /tmp/${i}_sslkey_creds + echo "confluent" > /tmp/${i}_keystore_creds + echo "confluent" > /tmp/${i}_truststore_creds + + keytool -noprompt -destkeystore /tmp/kafka.$i.truststore.jks -importkeystore -srckeystore "/usr/local/openjdk-8/lib/security/cacerts" -srcstorepass changeit -deststorepass confluent +done \ No newline at end of file From 70e4b8638f462751f645d9c40a142ef4d6009a5d Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 10 Dec 2024 15:25:21 +0100 Subject: [PATCH 094/659] fix for #6070 --- scripts/cli/playground | 17 ++++++++++++++++- scripts/cli/playground.json | 7 +++++++ scripts/cli/playground.yaml | 6 ++++++ scripts/cli/src/bashly.yml | 5 +++++ scripts/cli/src/commands/tools/certs-create.sh | 9 ++++++++- scripts/cli/src/ssl/certs-create.sh | 17 +++++++++++++---- 6 files changed, 55 insertions(+), 6 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index f34ef0d08d..42ea5e803c 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -18862,6 +18862,7 @@ playground_tools_certs_create_command() { # src/commands/tools/certs-create.sh output_folder="${args[--output-folder]}" verbose="${args[--verbose]}" + kerberos="${args[--kerberos]}" # Convert the space delimited string to an array eval "containers=(${args[--container]})" @@ -18877,6 +18878,12 @@ playground_tools_certs_create_command() { maybe_redirect_output="" fi + kerberos_mode=0 + if [[ -n "$kerberos" ]] + then + kerberos_mode=1 + fi + container_list="${containers[*]}" new_open_ssl=0 @@ -18888,7 +18895,7 @@ playground_tools_certs_create_command() { cd "${output_folder}" cp $root_folder/scripts/cli/src/ssl/certs-create.sh . log "🔐 Generate keys and certificates in folder ${output_folder}" - docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" + docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl $kerberos_mode && chown -R $(id -u $USER):$(id -g $USER) /tmp/" } # :command.function @@ -32462,6 +32469,14 @@ playground_tools_certs_create_parse_requirements() { fi ;; + # :flag.case + --kerberos) + + # :flag.case_no_arg + args['--kerberos']=1 + shift + ;; + -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index 75c828ac71..461b8757bc 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -1091,6 +1091,13 @@ ], "argument": "FOLDER", "description": "📁 Folder where certificates are created\n\nRequired: ✓ Yes\n" + }, + { + "names": [ + "--kerberos" + ], + "argument": "", + "description": "add \"kerberos-demo.local\" to dns names (required for kerberos)\n" } ] } diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index 170d47ff81..c0ed7e7e2b 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -1215,6 +1215,12 @@ subcommands: Required: ✓ Yes + - names: + - --kerberos + argument: "" + description: | + add "kerberos-demo.local" to dns names (required for kerberos) + - name: debug description: | 🐞 Debug commands diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index 52e9ba10c1..c2cdaf9261 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -1613,6 +1613,11 @@ commands: arg: folder help: |- 📁 Folder where certificates are created + - long: --kerberos + required: false + private: true + help: |- + add "kerberos-demo.local" to dns names (required for kerberos) - name: debug expose: always diff --git a/scripts/cli/src/commands/tools/certs-create.sh b/scripts/cli/src/commands/tools/certs-create.sh index 74623e2ed0..3bc186cd0c 100644 --- a/scripts/cli/src/commands/tools/certs-create.sh +++ b/scripts/cli/src/commands/tools/certs-create.sh @@ -1,5 +1,6 @@ output_folder="${args[--output-folder]}" verbose="${args[--verbose]}" +kerberos="${args[--kerberos]}" # Convert the space delimited string to an array eval "containers=(${args[--container]})" @@ -15,6 +16,12 @@ then maybe_redirect_output="" fi +kerberos_mode=0 +if [[ -n "$kerberos" ]] +then + kerberos_mode=1 +fi + container_list="${containers[*]}" new_open_ssl=0 @@ -26,4 +33,4 @@ mkdir -p "${output_folder}" cd "${output_folder}" cp $root_folder/scripts/cli/src/ssl/certs-create.sh . log "🔐 Generate keys and certificates in folder ${output_folder}" -docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" \ No newline at end of file +docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl $kerberos_mode && chown -R $(id -u $USER):$(id -g $USER) /tmp/" \ No newline at end of file diff --git a/scripts/cli/src/ssl/certs-create.sh b/scripts/cli/src/ssl/certs-create.sh index e8cfb9e1dd..60895eabf8 100755 --- a/scripts/cli/src/ssl/certs-create.sh +++ b/scripts/cli/src/ssl/certs-create.sh @@ -3,6 +3,7 @@ # Split the argument into an array IFS=' ' read -r -a containers <<< "$1" new_open_ssl=$2 +kerberos_mode=$3 if [[ $new_open_ssl -eq 1 ]] then @@ -15,6 +16,14 @@ else maybe_nomac="" fi +if [[ $kerberos_mode -eq 1 ]] +then + maybe_kerberos=".kerberos-demo.local" +else + maybe_kerberos="" +fi + + # Cleanup files rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile @@ -27,7 +36,7 @@ do keytool -genkey -noprompt \ -alias ${container} \ -dname "CN=${container},OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:${container},dns:localhost" \ + -ext "SAN=dns:${container}${maybe_kerberos},dns:localhost" \ -keystore /tmp/kafka.${container}.keystore.jks \ -keyalg RSA \ -storepass confluent \ @@ -35,7 +44,7 @@ do -storetype pkcs12 # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.${container}.keystore.jks -alias ${container} -certreq -file /tmp/${container}.csr -storepass confluent -keypass confluent -ext "SAN=dns:${container},dns:localhost" + keytool -keystore /tmp/kafka.${container}.keystore.jks -alias ${container} -certreq -file /tmp/${container}.csr -storepass confluent -keypass confluent -ext "SAN=dns:${container}${maybe_kerberos},dns:localhost" #openssl req -in ${container}.csr -text -noout cat << EOF > /tmp/extfile @@ -48,7 +57,7 @@ CN = ${container} [v3_req] subjectAltName = @alt_names [alt_names] -DNS.1 = ${container} +DNS.1 = ${container}${maybe_kerberos} DNS.2 = localhost EOF # Sign the host certificate with the certificate authority (CA) @@ -58,7 +67,7 @@ EOF keytool -noprompt -keystore /tmp/kafka.${container}.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.${container}.keystore.jks -alias ${container} -import -file /tmp/${container}-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:${container},dns:localhost" + keytool -noprompt -keystore /tmp/kafka.${container}.keystore.jks -alias ${container} -import -file /tmp/${container}-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:${container}${maybe_kerberos},dns:localhost" # Create truststore and import the CA cert keytool -noprompt -keystore /tmp/kafka.${container}.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent From 3ecde7feea8883ded4af92a9e81371e4a7060d81 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 10 Dec 2024 15:28:27 +0100 Subject: [PATCH 095/659] #6070 --- environment/ssl_kerberos/start.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment/ssl_kerberos/start.sh b/environment/ssl_kerberos/start.sh index 30396b17d4..dc206160e6 100755 --- a/environment/ssl_kerberos/start.sh +++ b/environment/ssl_kerberos/start.sh @@ -11,7 +11,7 @@ check_docker_compose_version check_bash_version check_playground_version -playground tools certs-create --output-folder "${PWD}/../../environment/ssl_kerberos/security" +playground tools certs-create --output-folder "${PWD}/../../environment/ssl_kerberos/security" --kerberos # Starting kerberos, # Avoiding starting up all services at the begining to generate the keytab first From 502617f9a7f669071c1078ff4d4d6bc7791aacf8 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 10 Dec 2024 15:56:07 +0100 Subject: [PATCH 096/659] fix #6070 --- environment/ssl_kerberos/start.sh | 2 +- scripts/cli/playground | 17 +---------------- scripts/cli/playground.json | 7 ------- scripts/cli/playground.yaml | 6 ------ scripts/cli/src/bashly.yml | 5 ----- scripts/cli/src/commands/tools/certs-create.sh | 9 +-------- scripts/cli/src/ssl/certs-create.sh | 18 +++++------------- 7 files changed, 8 insertions(+), 56 deletions(-) diff --git a/environment/ssl_kerberos/start.sh b/environment/ssl_kerberos/start.sh index dc206160e6..30396b17d4 100755 --- a/environment/ssl_kerberos/start.sh +++ b/environment/ssl_kerberos/start.sh @@ -11,7 +11,7 @@ check_docker_compose_version check_bash_version check_playground_version -playground tools certs-create --output-folder "${PWD}/../../environment/ssl_kerberos/security" --kerberos +playground tools certs-create --output-folder "${PWD}/../../environment/ssl_kerberos/security" # Starting kerberos, # Avoiding starting up all services at the begining to generate the keytab first diff --git a/scripts/cli/playground b/scripts/cli/playground index 42ea5e803c..f34ef0d08d 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -18862,7 +18862,6 @@ playground_tools_certs_create_command() { # src/commands/tools/certs-create.sh output_folder="${args[--output-folder]}" verbose="${args[--verbose]}" - kerberos="${args[--kerberos]}" # Convert the space delimited string to an array eval "containers=(${args[--container]})" @@ -18878,12 +18877,6 @@ playground_tools_certs_create_command() { maybe_redirect_output="" fi - kerberos_mode=0 - if [[ -n "$kerberos" ]] - then - kerberos_mode=1 - fi - container_list="${containers[*]}" new_open_ssl=0 @@ -18895,7 +18888,7 @@ playground_tools_certs_create_command() { cd "${output_folder}" cp $root_folder/scripts/cli/src/ssl/certs-create.sh . log "🔐 Generate keys and certificates in folder ${output_folder}" - docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl $kerberos_mode && chown -R $(id -u $USER):$(id -g $USER) /tmp/" + docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" } # :command.function @@ -32469,14 +32462,6 @@ playground_tools_certs_create_parse_requirements() { fi ;; - # :flag.case - --kerberos) - - # :flag.case_no_arg - args['--kerberos']=1 - shift - ;; - -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index 461b8757bc..75c828ac71 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -1091,13 +1091,6 @@ ], "argument": "FOLDER", "description": "📁 Folder where certificates are created\n\nRequired: ✓ Yes\n" - }, - { - "names": [ - "--kerberos" - ], - "argument": "", - "description": "add \"kerberos-demo.local\" to dns names (required for kerberos)\n" } ] } diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index c0ed7e7e2b..170d47ff81 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -1215,12 +1215,6 @@ subcommands: Required: ✓ Yes - - names: - - --kerberos - argument: "" - description: | - add "kerberos-demo.local" to dns names (required for kerberos) - - name: debug description: | 🐞 Debug commands diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index c2cdaf9261..52e9ba10c1 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -1613,11 +1613,6 @@ commands: arg: folder help: |- 📁 Folder where certificates are created - - long: --kerberos - required: false - private: true - help: |- - add "kerberos-demo.local" to dns names (required for kerberos) - name: debug expose: always diff --git a/scripts/cli/src/commands/tools/certs-create.sh b/scripts/cli/src/commands/tools/certs-create.sh index 3bc186cd0c..74623e2ed0 100644 --- a/scripts/cli/src/commands/tools/certs-create.sh +++ b/scripts/cli/src/commands/tools/certs-create.sh @@ -1,6 +1,5 @@ output_folder="${args[--output-folder]}" verbose="${args[--verbose]}" -kerberos="${args[--kerberos]}" # Convert the space delimited string to an array eval "containers=(${args[--container]})" @@ -16,12 +15,6 @@ then maybe_redirect_output="" fi -kerberos_mode=0 -if [[ -n "$kerberos" ]] -then - kerberos_mode=1 -fi - container_list="${containers[*]}" new_open_ssl=0 @@ -33,4 +26,4 @@ mkdir -p "${output_folder}" cd "${output_folder}" cp $root_folder/scripts/cli/src/ssl/certs-create.sh . log "🔐 Generate keys and certificates in folder ${output_folder}" -docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl $kerberos_mode && chown -R $(id -u $USER):$(id -g $USER) /tmp/" \ No newline at end of file +docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" \ No newline at end of file diff --git a/scripts/cli/src/ssl/certs-create.sh b/scripts/cli/src/ssl/certs-create.sh index 60895eabf8..c0dbeebbb0 100755 --- a/scripts/cli/src/ssl/certs-create.sh +++ b/scripts/cli/src/ssl/certs-create.sh @@ -3,7 +3,6 @@ # Split the argument into an array IFS=' ' read -r -a containers <<< "$1" new_open_ssl=$2 -kerberos_mode=$3 if [[ $new_open_ssl -eq 1 ]] then @@ -16,14 +15,6 @@ else maybe_nomac="" fi -if [[ $kerberos_mode -eq 1 ]] -then - maybe_kerberos=".kerberos-demo.local" -else - maybe_kerberos="" -fi - - # Cleanup files rm -f /tmp/*.crt /tmp/*.csr /tmp/*_creds /tmp/*.jks /tmp/*.srl /tmp/*.key /tmp/*.pem /tmp/*.der /tmp/*.p12 /tmp/extfile @@ -36,7 +27,7 @@ do keytool -genkey -noprompt \ -alias ${container} \ -dname "CN=${container},OU=TEST,O=CONFLUENT,L=PaloAlto,S=Ca,C=US" \ - -ext "SAN=dns:${container}${maybe_kerberos},dns:localhost" \ + -ext "SAN=dns:${container},dns:${container}.kerberos-demo.local,dns:localhost" \ -keystore /tmp/kafka.${container}.keystore.jks \ -keyalg RSA \ -storepass confluent \ @@ -44,7 +35,7 @@ do -storetype pkcs12 # Create the certificate signing request (CSR) - keytool -keystore /tmp/kafka.${container}.keystore.jks -alias ${container} -certreq -file /tmp/${container}.csr -storepass confluent -keypass confluent -ext "SAN=dns:${container}${maybe_kerberos},dns:localhost" + keytool -keystore /tmp/kafka.${container}.keystore.jks -alias ${container} -certreq -file /tmp/${container}.csr -storepass confluent -keypass confluent -ext "SAN=dns:${container},dns:${container}.kerberos-demo.local,dns:localhost" #openssl req -in ${container}.csr -text -noout cat << EOF > /tmp/extfile @@ -57,8 +48,9 @@ CN = ${container} [v3_req] subjectAltName = @alt_names [alt_names] -DNS.1 = ${container}${maybe_kerberos} +DNS.1 = ${container} DNS.2 = localhost +DNS.3 = ${container}.kerberos-demo.local EOF # Sign the host certificate with the certificate authority (CA) openssl x509 -req -CA /tmp/snakeoil-ca-1.crt -CAkey /tmp/snakeoil-ca-1.key -in /tmp/${container}.csr -out /tmp/${container}-ca1-signed.crt -days 9999 -CAcreateserial -passin pass:confluent -extensions v3_req -extfile /tmp/extfile $maybe_provider @@ -67,7 +59,7 @@ EOF keytool -noprompt -keystore /tmp/kafka.${container}.keystore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent # Sign and import the host certificate into the keystore - keytool -noprompt -keystore /tmp/kafka.${container}.keystore.jks -alias ${container} -import -file /tmp/${container}-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:${container}${maybe_kerberos},dns:localhost" + keytool -noprompt -keystore /tmp/kafka.${container}.keystore.jks -alias ${container} -import -file /tmp/${container}-ca1-signed.crt -storepass confluent -keypass confluent -ext "SAN=dns:${container},dns:${container}.kerberos-demo.local,dns:localhost" # Create truststore and import the CA cert keytool -noprompt -keystore /tmp/kafka.${container}.truststore.jks -alias CARoot -import -file /tmp/snakeoil-ca-1.crt -storepass confluent -keypass confluent From 2b5ad304103e7cc3d4c29327f2a9d72736dfb224 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 10 Dec 2024 16:13:31 +0100 Subject: [PATCH 097/659] fix #6068 --- environment/rbac-sasl-plain/start.sh | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/environment/rbac-sasl-plain/start.sh b/environment/rbac-sasl-plain/start.sh index 96ae157bd7..33f76b2acf 100755 --- a/environment/rbac-sasl-plain/start.sh +++ b/environment/rbac-sasl-plain/start.sh @@ -57,10 +57,33 @@ cd - # Generating public and private keys for token signing log "Generating public and private keys for token signing" + + +maybe_provider="" +if version_gt $TAG "7.7.99" +then + maybe_provider="-provider base" +fi + mkdir -p ../../environment/rbac-sasl-plain/conf cd ../../environment/rbac-sasl-plain/ -docker run -v $PWD:/tmp -u0 ${CP_KAFKA_IMAGE}:${TAG} bash -c "mkdir -p /tmp/conf; openssl genrsa -out /tmp/conf/keypair.pem 2048; openssl rsa -in /tmp/conf/keypair.pem -outform PEM -pubout -out /tmp/conf/public.pem && chown -R $(id -u $USER):$(id -g $USER) /tmp/conf && chmod 644 /tmp/conf/keypair.pem" +OLDDIR=$PWD +mkdir -p conf +docker run -v $PWD:/tmp -u0 alpine/openssl genrsa -out /tmp/conf/keypair.pem 2048 +docker run -v $PWD:/tmp -u0 alpine/openssl rsa -in /tmp/conf/keypair.pem -outform PEM -pubout -out /tmp/conf/public.pem +cd conf +if [[ "$OSTYPE" == "darwin"* ]] +then + # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 + chmod -R a+rw . +else + # on CI, docker is run as runneradmin user, need to use sudo + ls -lrt + sudo chmod -R a+rw . + ls -lrt +fi cd - +cd ${OLDDIR} # Bring up base cluster and Confluent CLI if [ -f "${DOCKER_COMPOSE_FILE_OVERRIDE}" ] From 15c438892364b9adbe9f0b40d1179aaeb83c253e Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 13 Dec 2024 15:18:26 +0100 Subject: [PATCH 098/659] Allow to override CP_CONNECT_IMAGE #6082 --- scripts/utils.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/utils.sh b/scripts/utils.sh index 34d4dbd423..86245d594f 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -50,7 +50,11 @@ then export CP_KSQL_CLI_IMAGE=confluentinc/cp-ksqldb-cli:latest export LEGACY_CONNECT_VALUE_CONVERTER_SCHEMA_REGISTRY_SSL="" export CONNECT_USER="appuser" - export CP_CONNECT_IMAGE=confluentinc/cp-server-connect-base + + if [ -z "$CP_CONNECT_IMAGE" ] + then + export CP_CONNECT_IMAGE=confluentinc/cp-server-connect-base + fi set_kafka_client_tag else if [ -z "$CP_KAFKA_IMAGE" ] @@ -99,7 +103,10 @@ else export CP_CONNECT_IMAGE=confluentinc/cp-server-connect-base fi else - export CP_CONNECT_IMAGE=confluentinc/cp-kafka-connect-base + if [ -z "$CP_CONNECT_IMAGE" ] + then + export CP_CONNECT_IMAGE=confluentinc/cp-kafka-connect-base + fi fi second_version=5.3.99 if version_gt $first_version $second_version; then From 5f98190b2c0564565d1c0cdc18a1702a29a03d62 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 13 Dec 2024 15:20:11 +0100 Subject: [PATCH 099/659] CP_CONNECT_IMAGE: "confluentinc/cp-kafka-connect-base" --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2b6c290b9..354c0d1c55 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -320,6 +320,7 @@ jobs: MONGODB_ATLAS_HOST: ${{ secrets.MONGODB_ATLAS_HOST}} MONGODB_ATLAS_USER: ${{ secrets.MONGODB_ATLAS_USER}} MONGODB_ATLAS_PASSWORD: ${{ secrets.MONGODB_ATLAS_PASSWORD}} + CP_CONNECT_IMAGE: "confluentinc/cp-kafka-connect-base" execute_one_test: if: ${{ github.event.inputs.test_name != '' }} @@ -510,6 +511,7 @@ jobs: MONGODB_ATLAS_HOST: ${{ secrets.MONGODB_ATLAS_HOST}} MONGODB_ATLAS_USER: ${{ secrets.MONGODB_ATLAS_USER}} MONGODB_ATLAS_PASSWORD: ${{ secrets.MONGODB_ATLAS_PASSWORD}} + CP_CONNECT_IMAGE: "confluentinc/cp-kafka-connect-base" post-build: name: Cleanup resources and Update README From d73f6420b048b1d22ab51baff655c4ef2a30fbaf Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 13 Dec 2024 16:26:27 +0100 Subject: [PATCH 100/659] wip --- scripts/utils.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/utils.sh b/scripts/utils.sh index 86245d594f..b139e124ff 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -100,7 +100,10 @@ else logwarn "Workaround for ST-6539, using custom image vdesabou/cp-server-connect-base !" export CP_CONNECT_IMAGE=vdesabou/cp-server-connect-base else - export CP_CONNECT_IMAGE=confluentinc/cp-server-connect-base + if [ -z "$CP_CONNECT_IMAGE" ] + then + export CP_CONNECT_IMAGE=confluentinc/cp-server-connect-base + fi fi else if [ -z "$CP_CONNECT_IMAGE" ] From 577beac3ae83a2ac1d2cf334722a1bd4bcb6fea1 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 16 Dec 2024 10:17:47 +0100 Subject: [PATCH 101/659] removed CP_CONNECT_IMAGE --- .github/workflows/ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 354c0d1c55..a2b6c290b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -320,7 +320,6 @@ jobs: MONGODB_ATLAS_HOST: ${{ secrets.MONGODB_ATLAS_HOST}} MONGODB_ATLAS_USER: ${{ secrets.MONGODB_ATLAS_USER}} MONGODB_ATLAS_PASSWORD: ${{ secrets.MONGODB_ATLAS_PASSWORD}} - CP_CONNECT_IMAGE: "confluentinc/cp-kafka-connect-base" execute_one_test: if: ${{ github.event.inputs.test_name != '' }} @@ -511,7 +510,6 @@ jobs: MONGODB_ATLAS_HOST: ${{ secrets.MONGODB_ATLAS_HOST}} MONGODB_ATLAS_USER: ${{ secrets.MONGODB_ATLAS_USER}} MONGODB_ATLAS_PASSWORD: ${{ secrets.MONGODB_ATLAS_PASSWORD}} - CP_CONNECT_IMAGE: "confluentinc/cp-kafka-connect-base" post-build: name: Cleanup resources and Update README From 755f6a4d7182bbe6165f09aa9da2c55ed95b8037 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 16 Dec 2024 11:17:36 +0100 Subject: [PATCH 102/659] update --- secrets.tar.gpg | Bin 7454 -> 7795 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/secrets.tar.gpg b/secrets.tar.gpg index a6e5e02b59209b0dc51a0c0db5cccd53cee1ad3f..9189ba3e7a225ec94ea541d0fa3494190f2b00b6 100644 GIT binary patch literal 7795 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 F!UJ-1QtSW# literal 7454 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 From b2205551c19d80c8f377b31d47aac1579440b8a3 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 18 Dec 2024 16:30:58 +0100 Subject: [PATCH 103/659] Flink is missing in CLI Menu #6076 --- scripts/cli/completions.bash | 2 +- scripts/cli/playground | 64 ++++++++++++++++++++------------- scripts/cli/playground.json | 7 ++++ scripts/cli/playground.yaml | 12 +++++++ scripts/cli/src/bashly.yml | 12 +++++++ scripts/cli/src/commands/run.sh | 51 +++++++++++++------------- 6 files changed, 99 insertions(+), 49 deletions(-) diff --git a/scripts/cli/completions.bash b/scripts/cli/completions.bash index 01381e2cdf..309a6e2965 100644 --- a/scripts/cli/completions.bash +++ b/scripts/cli/completions.bash @@ -1309,7 +1309,7 @@ _playground_completions() { ;; *'run'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--cluster-cloud --cluster-creds --cluster-environment --cluster-name --cluster-region --cluster-schema-registry-creds --cluster-type --connector-jar --connector-tag --connector-zip --enable-conduktor --enable-control-center --enable-jmx-grafana --enable-kcat --enable-ksqldb --enable-multiple-brokers --enable-multiple-connect-workers --enable-rest-proxy --enable-sql-datagen --environment --file --help --open --tag -f -h -o")" -- "$cur") + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--cluster-cloud --cluster-creds --cluster-environment --cluster-name --cluster-region --cluster-schema-registry-creds --cluster-type --connector-jar --connector-tag --connector-zip --enable-conduktor --enable-control-center --enable-flink --enable-jmx-grafana --enable-kcat --enable-ksqldb --enable-multiple-brokers --enable-multiple-connect-workers --enable-rest-proxy --enable-sql-datagen --environment --file --help --open --tag -f -h -o")" -- "$cur") ;; *'-o') diff --git a/scripts/cli/playground b/scripts/cli/playground index f34ef0d08d..89d938bd8f 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -1611,6 +1611,11 @@ playground_run_usage() { printf " 💠 Enable Control Center\n \n By default, control-center container is not started for every test\n \n Control Center is reachable at http://127.0.0.1:9021\n" echo + # :flag.usage + printf " %s\n" "$(magenta "--enable-flink")" + printf " 🐿️ Enable Flink\n \n By default, flink is not started for every test\n \n Once enabled, the CLI will ask if you need to download any connectors. Based\n on the response, you can download one or more connectors from Flink maven\n repository.\n \n Flink UI is reacheable using http://127.0.0.1:8081 within the flink child\n directory. If you enable Flink by starting connector deployment,\n http://127.0.0.1:18081 will be used.\n" + echo + # :flag.usage printf " %s\n" "$(magenta "--enable-conduktor")" printf " 🐺 Enable Conduktor Platform\n \n By default, Conduktor Platform container is not started for every test\n \n Conduktor is reachable at http://127.0.0.1:8080/console (admin/admin)\n" @@ -13575,6 +13580,7 @@ playground_run_command() { enable_ksqldb="${args[--enable-ksqldb]}" enable_rest_proxy="${args[--enable-rest-proxy]}" enable_c3="${args[--enable-control-center]}" + enable_flink="${args[--enable-flink]}" enable_conduktor="${args[--enable-conduktor]}" enable_multiple_brokers="${args[--enable-multiple-brokers]}" enable_multiple_connect_workers="${args[--enable-multiple-connect-workers]}" @@ -14073,9 +14079,10 @@ playground_run_command() { MENU_ENABLE_BROKERS="3️⃣ Enabling multiple brokers $(printf '%*s' $((${MAX_LENGTH}-28-${#MENU_ENABLE_BROKERS})) ' ') --enable-multiple-broker" MENU_ENABLE_CONNECT_WORKERS="🥉 Enabling multiple connect workers $(printf '%*s' $((${MAX_LENGTH}-36-${#MENU_ENABLE_CONNECT_WORKERS})) ' ') --enable-multiple-connect-workers" MENU_ENABLE_KCAT="🐈 Enabling kcat $(printf '%*s' $((${MAX_LENGTH}-16-${#MENU_ENABLE_KCAT})) ' ') --enable-kcat" - MENU_ENABLE_SQL_DATAGEN="🌪️ Enable SQL Datagen injection $(printf '%*s' $((${MAX_LENGTH}-33-${#MENU_ENABLE_SQL_DATAGEN})) ' ') --enable-sql-datagen" #19 + MENU_ENABLE_SQL_DATAGEN="🌪️ Enable SQL Datagen injection $(printf '%*s' $((${MAX_LENGTH}-32-${#MENU_ENABLE_SQL_DATAGEN})) ' ') --enable-sql-datagen" #19 + MENU_ENABLE_FLINK="🐿️ Enable Flink $(printf '%*s' $((${MAX_LENGTH}-15-${#MENU_ENABLE_FLINK})) ' ') --enable-flink" #20 - readonly MENU_DISABLE_KSQLDB="❌🎏 Disable ksqlDB" #20 + readonly MENU_DISABLE_KSQLDB="❌🎏 Disable ksqlDB" #21 readonly MENU_DISABLE_C3="❌💠 Disable Control Center" readonly MENU_DISABLE_CONDUKTOR="❌🐺 Disable Conduktor Platform" readonly MENU_DISABLE_RP="❌🧲 Disable Rest Proxy" @@ -14083,11 +14090,12 @@ playground_run_command() { readonly MENU_DISABLE_BROKERS="❌3️⃣ Disabling multiple brokers" readonly MENU_DISABLE_CONNECT_WORKERS="❌🥉 Disabling multiple connect workers" readonly MENU_DISABLE_KCAT="❌🐈 Disabling kcat" - readonly MENU_DISABLE_SQL_DATAGEN="❌🌪️ Disable SQL Datagen injection" #27 + readonly MENU_DISABLE_SQL_DATAGEN="❌🌪️ Disable SQL Datagen injection" #29 + readonly MENU_DISABLE_FLINK="❌🐿️ Disable Flink" #30 readonly MENU_SEPARATOR_FEATURES="--------------------options-----------------------" - MENU_CLUSTER_TYPE="🔋 Cluster type $(printf '%*s' $((${MAX_LENGTH}-15-${#MENU_CLUSTER_TYPE})) ' ') --cluster-type" #29 + MENU_CLUSTER_TYPE="🔋 Cluster type $(printf '%*s' $((${MAX_LENGTH}-15-${#MENU_CLUSTER_TYPE})) ' ') --cluster-type" #31 MENU_CLUSTER_CLOUD="🌤 Cloud provider $(printf '%*s' $((${MAX_LENGTH}-17-${#MENU_CLUSTER_CLOUD})) ' ') --cluster-cloud" MENU_CLUSTER_REGION="🗺 Cloud region $(printf '%*s' $((${MAX_LENGTH}-15-${#MENU_CLUSTER_REGION})) ' ') --cluster-region" MENU_CLUSTER_ENVIRONMENT="🌐 Environment id $(printf '%*s' $((${MAX_LENGTH}-17-${#MENU_CLUSTER_ENVIRONMENT})) ' ') --cluster-environment" @@ -14096,7 +14104,7 @@ playground_run_command() { MENU_CLUSTER_CREDS="🔒 Kafka api key & secret $(printf '%*s' $((${MAX_LENGTH}-25-${#MENU_CLUSTER_CREDS})) ' ') --cluster-creds" MENU_CLUSTER_SR_CREDS="🔰 Schema registry api key & secret $(printf '%*s' $((${MAX_LENGTH}-35-${#MENU_CLUSTER_SR_CREDS})) ' ') --cluster-schema-registry-creds" - readonly MENU_SEPARATOR_CLOUD="-----------------confluent cloud------------------" #36 + readonly MENU_SEPARATOR_CLOUD="-----------------confluent cloud------------------" #38 readonly MENU_GO_BACK="🔙 Go back" @@ -14135,13 +14143,13 @@ playground_run_command() { while [ $stop != 1 ] do has_error=0 - options=("$MENU_LETS_GO" "$MENU_PROBLEM" "$MENU_OPEN_FILE" "$MENU_OPEN_DOCS" "$MENU_SEPARATOR" "$MENU_TAG" "$MENU_CONNECTOR_TAG" "$MENU_CONNECTOR_ZIP" "$MENU_CONNECTOR_JAR" "$MENU_ENVIRONMENT" "$MENU_SEPARATOR" "$MENU_ENABLE_KSQLDB" "$MENU_ENABLE_C3" "$MENU_ENABLE_CONDUKTOR" "$MENU_ENABLE_RP" "$MENU_ENABLE_GRAFANA" "$MENU_ENABLE_BROKERS" "$MENU_ENABLE_CONNECT_WORKERS" "$MENU_ENABLE_KCAT" "$MENU_ENABLE_SQL_DATAGEN" "$MENU_DISABLE_KSQLDB" "$MENU_DISABLE_C3" "$MENU_DISABLE_CONDUKTOR" "$MENU_DISABLE_RP" "$MENU_DISABLE_GRAFANA" "$MENU_DISABLE_BROKERS" "$MENU_DISABLE_CONNECT_WORKERS" "$MENU_DISABLE_KCAT" "$MENU_DISABLE_SQL_DATAGEN" "$MENU_SEPARATOR_FEATURES" "$MENU_CLUSTER_TYPE" "$MENU_CLUSTER_CLOUD" "$MENU_CLUSTER_REGION" "$MENU_CLUSTER_ENVIRONMENT" "$MENU_CLUSTER_NAME" "$MENU_CLUSTER_CREDS" "$MENU_CLUSTER_SR_CREDS" "$MENU_SEPARATOR_CLOUD" "$MENU_GO_BACK") + options=("$MENU_LETS_GO" "$MENU_PROBLEM" "$MENU_OPEN_FILE" "$MENU_OPEN_DOCS" "$MENU_SEPARATOR" "$MENU_TAG" "$MENU_CONNECTOR_TAG" "$MENU_CONNECTOR_ZIP" "$MENU_CONNECTOR_JAR" "$MENU_ENVIRONMENT" "$MENU_SEPARATOR" "$MENU_ENABLE_KSQLDB" "$MENU_ENABLE_C3" "$MENU_ENABLE_CONDUKTOR" "$MENU_ENABLE_RP" "$MENU_ENABLE_GRAFANA" "$MENU_ENABLE_BROKERS" "$MENU_ENABLE_CONNECT_WORKERS" "$MENU_ENABLE_KCAT" "$MENU_ENABLE_SQL_DATAGEN" "$MENU_ENABLE_FLINK" "$MENU_DISABLE_KSQLDB" "$MENU_DISABLE_C3" "$MENU_DISABLE_CONDUKTOR" "$MENU_DISABLE_RP" "$MENU_DISABLE_GRAFANA" "$MENU_DISABLE_BROKERS" "$MENU_DISABLE_CONNECT_WORKERS" "$MENU_DISABLE_KCAT" "$MENU_DISABLE_SQL_DATAGEN" "$MENU_DISABLE_FLINK" "$MENU_SEPARATOR_FEATURES" "$MENU_CLUSTER_TYPE" "$MENU_CLUSTER_CLOUD" "$MENU_CLUSTER_REGION" "$MENU_CLUSTER_ENVIRONMENT" "$MENU_CLUSTER_NAME" "$MENU_CLUSTER_CREDS" "$MENU_CLUSTER_SR_CREDS" "$MENU_SEPARATOR_CLOUD" "$MENU_GO_BACK") if [[ $test_file == *"ccloud"* ]] || [ "$PLAYGROUND_ENVIRONMENT" == "ccloud" ] then if [[ $test_file == *"fully-managed"* ]] then - for((i=5;i<30;i++)); do + for((i=5;i<32;i++)); do unset "options[$i]" done fi @@ -14150,10 +14158,10 @@ playground_run_command() { unset 'options[16]' unset 'options[17]' - unset 'options[23]' unset 'options[24]' unset 'options[25]' unset 'options[26]' + unset 'options[27]' if [[ -n "$cluster_type" ]] || [[ -n "$cluster_cloud" ]] || [[ -n "$cluster_region" ]] || [[ -n "$cluster_environment" ]] || [[ -n "$cluster_creds" ]] || [[ -n "$cluster_schema_registry_creds" ]] then @@ -14296,19 +14304,19 @@ playground_run_command() { fi fi else # end of ccloud - unset 'options[30]' - unset 'options[31]' unset 'options[32]' unset 'options[33]' unset 'options[34]' unset 'options[35]' unset 'options[36]' unset 'options[37]' - + unset 'options[38]' unset 'options[39]' - unset 'options[40]' + unset 'options[41]' unset 'options[42]' + unset 'options[43]' + unset 'options[44]' fi if [ $connector_example == 0 ] @@ -14333,61 +14341,61 @@ playground_run_command() { then unset 'options[11]' else - unset 'options[20]' + unset 'options[21]' fi if [ ! -z $ENABLE_CONTROL_CENTER ] then unset 'options[12]' else - unset 'options[21]' + unset 'options[22]' fi if [ ! -z $ENABLE_CONDUKTOR ] then unset 'options[13]' else - unset 'options[22]' + unset 'options[23]' fi if [ ! -z $ENABLE_RESTPROXY ] then unset 'options[14]' else - unset 'options[23]' + unset 'options[24]' fi if [ ! -z $ENABLE_JMX_GRAFANA ] then unset 'options[15]' else - unset 'options[24]' + unset 'options[25]' fi if [ ! -z $ENABLE_KAFKA_NODES ] then unset 'options[16]' else - unset 'options[25]' + unset 'options[26]' fi if [ ! -z $ENABLE_CONNECT_NODES ] then unset 'options[17]' else - unset 'options[26]' + unset 'options[27]' fi if [ ! -z $ENABLE_KCAT ] then unset 'options[18]' else - unset 'options[27]' + unset 'options[28]' fi if [ ! -z $SQL_DATAGEN ] then unset 'options[19]' else - unset 'options[28]' + unset 'options[29]' fi if [ ! -z $ENABLE_FLINK ] then unset 'options[20]' else - unset 'options[29]' + unset 'options[30]' fi missing_env="" @@ -14597,13 +14605,13 @@ playground_run_command() { interactive_enable_c3="" fi - if [[ $res == *"$MENU_ENABLE_FL"* ]] + if [[ $res == *"$MENU_ENABLE_FLINK"* ]] then array_flag_list+=("--enable-flink") export ENABLE_FLINK=true interactive_enable_flink="true" fi - if [[ $res == *"$MENU_DISABLE_FL"* ]] + if [[ $res == *"$MENU_DISABLE_FLINK"* ]] then array_flag_list=("${array_flag_list[@]/"--enable-flink"}") unset ENABLE_FLINK @@ -28651,6 +28659,14 @@ playground_run_parse_requirements() { shift ;; + # :flag.case + --enable-flink) + + # :flag.case_no_arg + args['--enable-flink']=1 + shift + ;; + # :flag.case --enable-conduktor) diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index 75c828ac71..34ac53c786 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -160,6 +160,13 @@ "argument": "", "description": "💠 Enable Control Center\n\nBy default, control-center container is not started for every test\n\nControl Center is reachable at http://127.0.0.1:9021\n" }, + { + "names": [ + "--enable-flink" + ], + "argument": "", + "description": "🐿️ Enable Flink\n\nBy default, flink is not started for every test\n\nOnce enabled, the CLI will ask if you need to download any connectors. Based on the response, you can download one or more connectors from Flink maven repository.\n\nFlink UI is reacheable using http://127.0.0.1:8081 within the flink child directory. If you enable Flink by starting connector deployment, http://127.0.0.1:18081 will be used.\n" + }, { "names": [ "--enable-conduktor" diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index 170d47ff81..b66bed7c93 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -228,6 +228,18 @@ subcommands: Control Center is reachable at http://127.0.0.1:9021 + - names: + - --enable-flink + argument: "" + description: | + 🐿️ Enable Flink + + By default, flink is not started for every test + + Once enabled, the CLI will ask if you need to download any connectors. Based on the response, you can download one or more connectors from Flink maven repository. + + Flink UI is reacheable using http://127.0.0.1:8081 within the flink child directory. If you enable Flink by starting connector deployment, http://127.0.0.1:18081 will be used. + - names: - --enable-conduktor argument: "" diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index 52e9ba10c1..59ed7a7847 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -569,6 +569,18 @@ commands: By default, control-center container is not started for every test Control Center is reachable at http://127.0.0.1:9021 + - &enable-flink + long: --enable-flink + required: false + + help: |- + 🐿️ Enable Flink + + By default, flink is not started for every test + + Once enabled, the CLI will ask if you need to download any connectors. Based on the response, you can download one or more connectors from Flink maven repository. + + Flink UI is reacheable using http://127.0.0.1:8081 within the flink child directory. If you enable Flink by starting connector deployment, http://127.0.0.1:18081 will be used. - &enable-conduktor long: --enable-conduktor required: false diff --git a/scripts/cli/src/commands/run.sh b/scripts/cli/src/commands/run.sh index 7fae8b0c2e..160ef21d09 100644 --- a/scripts/cli/src/commands/run.sh +++ b/scripts/cli/src/commands/run.sh @@ -13,6 +13,7 @@ connector_jar="${args[--connector-jar]}" enable_ksqldb="${args[--enable-ksqldb]}" enable_rest_proxy="${args[--enable-rest-proxy]}" enable_c3="${args[--enable-control-center]}" +enable_flink="${args[--enable-flink]}" enable_conduktor="${args[--enable-conduktor]}" enable_multiple_brokers="${args[--enable-multiple-brokers]}" enable_multiple_connect_workers="${args[--enable-multiple-connect-workers]}" @@ -509,9 +510,10 @@ then MENU_ENABLE_BROKERS="3️⃣ Enabling multiple brokers $(printf '%*s' $((${MAX_LENGTH}-28-${#MENU_ENABLE_BROKERS})) ' ') --enable-multiple-broker" MENU_ENABLE_CONNECT_WORKERS="🥉 Enabling multiple connect workers $(printf '%*s' $((${MAX_LENGTH}-36-${#MENU_ENABLE_CONNECT_WORKERS})) ' ') --enable-multiple-connect-workers" MENU_ENABLE_KCAT="🐈 Enabling kcat $(printf '%*s' $((${MAX_LENGTH}-16-${#MENU_ENABLE_KCAT})) ' ') --enable-kcat" - MENU_ENABLE_SQL_DATAGEN="🌪️ Enable SQL Datagen injection $(printf '%*s' $((${MAX_LENGTH}-33-${#MENU_ENABLE_SQL_DATAGEN})) ' ') --enable-sql-datagen" #19 + MENU_ENABLE_SQL_DATAGEN="🌪️ Enable SQL Datagen injection $(printf '%*s' $((${MAX_LENGTH}-32-${#MENU_ENABLE_SQL_DATAGEN})) ' ') --enable-sql-datagen" #19 + MENU_ENABLE_FLINK="🐿️ Enable Flink $(printf '%*s' $((${MAX_LENGTH}-15-${#MENU_ENABLE_FLINK})) ' ') --enable-flink" #20 - readonly MENU_DISABLE_KSQLDB="❌🎏 Disable ksqlDB" #20 + readonly MENU_DISABLE_KSQLDB="❌🎏 Disable ksqlDB" #21 readonly MENU_DISABLE_C3="❌💠 Disable Control Center" readonly MENU_DISABLE_CONDUKTOR="❌🐺 Disable Conduktor Platform" readonly MENU_DISABLE_RP="❌🧲 Disable Rest Proxy" @@ -519,11 +521,12 @@ then readonly MENU_DISABLE_BROKERS="❌3️⃣ Disabling multiple brokers" readonly MENU_DISABLE_CONNECT_WORKERS="❌🥉 Disabling multiple connect workers" readonly MENU_DISABLE_KCAT="❌🐈 Disabling kcat" - readonly MENU_DISABLE_SQL_DATAGEN="❌🌪️ Disable SQL Datagen injection" #27 + readonly MENU_DISABLE_SQL_DATAGEN="❌🌪️ Disable SQL Datagen injection" #29 + readonly MENU_DISABLE_FLINK="❌🐿️ Disable Flink" #30 readonly MENU_SEPARATOR_FEATURES="--------------------options-----------------------" - MENU_CLUSTER_TYPE="🔋 Cluster type $(printf '%*s' $((${MAX_LENGTH}-15-${#MENU_CLUSTER_TYPE})) ' ') --cluster-type" #29 + MENU_CLUSTER_TYPE="🔋 Cluster type $(printf '%*s' $((${MAX_LENGTH}-15-${#MENU_CLUSTER_TYPE})) ' ') --cluster-type" #31 MENU_CLUSTER_CLOUD="🌤 Cloud provider $(printf '%*s' $((${MAX_LENGTH}-17-${#MENU_CLUSTER_CLOUD})) ' ') --cluster-cloud" MENU_CLUSTER_REGION="🗺 Cloud region $(printf '%*s' $((${MAX_LENGTH}-15-${#MENU_CLUSTER_REGION})) ' ') --cluster-region" MENU_CLUSTER_ENVIRONMENT="🌐 Environment id $(printf '%*s' $((${MAX_LENGTH}-17-${#MENU_CLUSTER_ENVIRONMENT})) ' ') --cluster-environment" @@ -532,7 +535,7 @@ then MENU_CLUSTER_CREDS="🔒 Kafka api key & secret $(printf '%*s' $((${MAX_LENGTH}-25-${#MENU_CLUSTER_CREDS})) ' ') --cluster-creds" MENU_CLUSTER_SR_CREDS="🔰 Schema registry api key & secret $(printf '%*s' $((${MAX_LENGTH}-35-${#MENU_CLUSTER_SR_CREDS})) ' ') --cluster-schema-registry-creds" - readonly MENU_SEPARATOR_CLOUD="-----------------confluent cloud------------------" #36 + readonly MENU_SEPARATOR_CLOUD="-----------------confluent cloud------------------" #38 readonly MENU_GO_BACK="🔙 Go back" @@ -570,13 +573,13 @@ then while [ $stop != 1 ] do has_error=0 - options=("$MENU_LETS_GO" "$MENU_PROBLEM" "$MENU_OPEN_FILE" "$MENU_OPEN_DOCS" "$MENU_SEPARATOR" "$MENU_TAG" "$MENU_CONNECTOR_TAG" "$MENU_CONNECTOR_ZIP" "$MENU_CONNECTOR_JAR" "$MENU_ENVIRONMENT" "$MENU_SEPARATOR" "$MENU_ENABLE_KSQLDB" "$MENU_ENABLE_C3" "$MENU_ENABLE_CONDUKTOR" "$MENU_ENABLE_RP" "$MENU_ENABLE_GRAFANA" "$MENU_ENABLE_BROKERS" "$MENU_ENABLE_CONNECT_WORKERS" "$MENU_ENABLE_KCAT" "$MENU_ENABLE_SQL_DATAGEN" "$MENU_DISABLE_KSQLDB" "$MENU_DISABLE_C3" "$MENU_DISABLE_CONDUKTOR" "$MENU_DISABLE_RP" "$MENU_DISABLE_GRAFANA" "$MENU_DISABLE_BROKERS" "$MENU_DISABLE_CONNECT_WORKERS" "$MENU_DISABLE_KCAT" "$MENU_DISABLE_SQL_DATAGEN" "$MENU_SEPARATOR_FEATURES" "$MENU_CLUSTER_TYPE" "$MENU_CLUSTER_CLOUD" "$MENU_CLUSTER_REGION" "$MENU_CLUSTER_ENVIRONMENT" "$MENU_CLUSTER_NAME" "$MENU_CLUSTER_CREDS" "$MENU_CLUSTER_SR_CREDS" "$MENU_SEPARATOR_CLOUD" "$MENU_GO_BACK") + options=("$MENU_LETS_GO" "$MENU_PROBLEM" "$MENU_OPEN_FILE" "$MENU_OPEN_DOCS" "$MENU_SEPARATOR" "$MENU_TAG" "$MENU_CONNECTOR_TAG" "$MENU_CONNECTOR_ZIP" "$MENU_CONNECTOR_JAR" "$MENU_ENVIRONMENT" "$MENU_SEPARATOR" "$MENU_ENABLE_KSQLDB" "$MENU_ENABLE_C3" "$MENU_ENABLE_CONDUKTOR" "$MENU_ENABLE_RP" "$MENU_ENABLE_GRAFANA" "$MENU_ENABLE_BROKERS" "$MENU_ENABLE_CONNECT_WORKERS" "$MENU_ENABLE_KCAT" "$MENU_ENABLE_SQL_DATAGEN" "$MENU_ENABLE_FLINK" "$MENU_DISABLE_KSQLDB" "$MENU_DISABLE_C3" "$MENU_DISABLE_CONDUKTOR" "$MENU_DISABLE_RP" "$MENU_DISABLE_GRAFANA" "$MENU_DISABLE_BROKERS" "$MENU_DISABLE_CONNECT_WORKERS" "$MENU_DISABLE_KCAT" "$MENU_DISABLE_SQL_DATAGEN" "$MENU_DISABLE_FLINK" "$MENU_SEPARATOR_FEATURES" "$MENU_CLUSTER_TYPE" "$MENU_CLUSTER_CLOUD" "$MENU_CLUSTER_REGION" "$MENU_CLUSTER_ENVIRONMENT" "$MENU_CLUSTER_NAME" "$MENU_CLUSTER_CREDS" "$MENU_CLUSTER_SR_CREDS" "$MENU_SEPARATOR_CLOUD" "$MENU_GO_BACK") if [[ $test_file == *"ccloud"* ]] || [ "$PLAYGROUND_ENVIRONMENT" == "ccloud" ] then if [[ $test_file == *"fully-managed"* ]] then - for((i=5;i<30;i++)); do + for((i=5;i<32;i++)); do unset "options[$i]" done fi @@ -585,10 +588,10 @@ then unset 'options[16]' unset 'options[17]' - unset 'options[23]' unset 'options[24]' unset 'options[25]' unset 'options[26]' + unset 'options[27]' if [[ -n "$cluster_type" ]] || [[ -n "$cluster_cloud" ]] || [[ -n "$cluster_region" ]] || [[ -n "$cluster_environment" ]] || [[ -n "$cluster_creds" ]] || [[ -n "$cluster_schema_registry_creds" ]] then @@ -725,19 +728,19 @@ then fi fi else # end of ccloud - unset 'options[30]' - unset 'options[31]' unset 'options[32]' unset 'options[33]' unset 'options[34]' unset 'options[35]' unset 'options[36]' unset 'options[37]' - + unset 'options[38]' unset 'options[39]' - unset 'options[40]' + unset 'options[41]' unset 'options[42]' + unset 'options[43]' + unset 'options[44]' fi if [ $connector_example == 0 ] @@ -762,61 +765,61 @@ then then unset 'options[11]' else - unset 'options[20]' + unset 'options[21]' fi if [ ! -z $ENABLE_CONTROL_CENTER ] then unset 'options[12]' else - unset 'options[21]' + unset 'options[22]' fi if [ ! -z $ENABLE_CONDUKTOR ] then unset 'options[13]' else - unset 'options[22]' + unset 'options[23]' fi if [ ! -z $ENABLE_RESTPROXY ] then unset 'options[14]' else - unset 'options[23]' + unset 'options[24]' fi if [ ! -z $ENABLE_JMX_GRAFANA ] then unset 'options[15]' else - unset 'options[24]' + unset 'options[25]' fi if [ ! -z $ENABLE_KAFKA_NODES ] then unset 'options[16]' else - unset 'options[25]' + unset 'options[26]' fi if [ ! -z $ENABLE_CONNECT_NODES ] then unset 'options[17]' else - unset 'options[26]' + unset 'options[27]' fi if [ ! -z $ENABLE_KCAT ] then unset 'options[18]' else - unset 'options[27]' + unset 'options[28]' fi if [ ! -z $SQL_DATAGEN ] then unset 'options[19]' else - unset 'options[28]' + unset 'options[29]' fi if [ ! -z $ENABLE_FLINK ] then unset 'options[20]' else - unset 'options[29]' + unset 'options[30]' fi missing_env="" @@ -1027,13 +1030,13 @@ then interactive_enable_c3="" fi - if [[ $res == *"$MENU_ENABLE_FL"* ]] + if [[ $res == *"$MENU_ENABLE_FLINK"* ]] then array_flag_list+=("--enable-flink") export ENABLE_FLINK=true interactive_enable_flink="true" fi - if [[ $res == *"$MENU_DISABLE_FL"* ]] + if [[ $res == *"$MENU_DISABLE_FLINK"* ]] then array_flag_list=("${array_flag_list[@]/"--enable-flink"}") unset ENABLE_FLINK From 2a7ce4c091b8a60a478f42deba8e6863f246dfd3 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 18 Dec 2024 17:07:43 +0100 Subject: [PATCH 104/659] fix --- scripts/cli/playground | 1 + scripts/cli/src/commands/tools/certs-create.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/scripts/cli/playground b/scripts/cli/playground index 89d938bd8f..f8c9596c59 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -18887,6 +18887,7 @@ playground_tools_certs_create_command() { container_list="${containers[*]}" + get_connect_image new_open_ssl=0 if version_gt $CONNECT_TAG "7.7.99" then diff --git a/scripts/cli/src/commands/tools/certs-create.sh b/scripts/cli/src/commands/tools/certs-create.sh index 74623e2ed0..3287efc9cd 100644 --- a/scripts/cli/src/commands/tools/certs-create.sh +++ b/scripts/cli/src/commands/tools/certs-create.sh @@ -17,6 +17,7 @@ fi container_list="${containers[*]}" +get_connect_image new_open_ssl=0 if version_gt $CONNECT_TAG "7.7.99" then From a116fd10c5e52dd4cf45051e4044f6cab07bc55d Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 19 Dec 2024 17:55:16 +0100 Subject: [PATCH 105/659] fix --- ccloud/fm-rabbitmq-sink/fully-managed-rabbitmq-sink-ssl.sh | 5 ++++- .../fm-rabbitmq-source/fully-managed-rabbitmq-source-ssl.sh | 5 ++++- connect/connect-rabbitmq-sink/rabbitmq-sink-ssl.sh | 4 ++++ connect/connect-rabbitmq-source/rabbitmq-source-ssl.sh | 5 ++++- reproduction-models | 2 +- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/ccloud/fm-rabbitmq-sink/fully-managed-rabbitmq-sink-ssl.sh b/ccloud/fm-rabbitmq-sink/fully-managed-rabbitmq-sink-ssl.sh index e85c651c1d..58aa0f7f3a 100755 --- a/ccloud/fm-rabbitmq-sink/fully-managed-rabbitmq-sink-ssl.sh +++ b/ccloud/fm-rabbitmq-sink/fully-managed-rabbitmq-sink-ssl.sh @@ -27,7 +27,10 @@ docker compose -f docker-compose.ssl.yml build docker compose -f docker-compose.ssl.yml down -v --remove-orphans docker compose -f docker-compose.ssl.yml up -d --quiet-pull -sleep 5 +playground container exec --command "chown rabbitmq:rabbitmq /tmp/*" --container rabbitmq +playground container restart --container rabbitmq + +sleep 10 log "Waiting for ngrok to start" while true diff --git a/ccloud/fm-rabbitmq-source/fully-managed-rabbitmq-source-ssl.sh b/ccloud/fm-rabbitmq-source/fully-managed-rabbitmq-source-ssl.sh index ad50baa658..641269185c 100755 --- a/ccloud/fm-rabbitmq-source/fully-managed-rabbitmq-source-ssl.sh +++ b/ccloud/fm-rabbitmq-source/fully-managed-rabbitmq-source-ssl.sh @@ -23,7 +23,10 @@ docker compose -f docker-compose.ssl.yml build docker compose -f docker-compose.ssl.yml down -v --remove-orphans docker compose -f docker-compose.ssl.yml up -d --quiet-pull -sleep 5 +playground container exec --command "chown rabbitmq:rabbitmq /tmp/*" --container rabbitmq +playground container restart --container rabbitmq + +sleep 10 log "Waiting for ngrok to start" while true diff --git a/connect/connect-rabbitmq-sink/rabbitmq-sink-ssl.sh b/connect/connect-rabbitmq-sink/rabbitmq-sink-ssl.sh index 2e790ac9c3..09b0f1476b 100755 --- a/connect/connect-rabbitmq-sink/rabbitmq-sink-ssl.sh +++ b/connect/connect-rabbitmq-sink/rabbitmq-sink-ssl.sh @@ -12,6 +12,10 @@ cd - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext-ssl.yml" +playground container exec --command "chown rabbitmq:rabbitmq /tmp/*" --container rabbitmq +playground container restart --container rabbitmq + +sleep 10 log "Create RabbitMQ exchange, queue and binding" docker exec -i rabbitmq rabbitmqadmin -u myuser -p mypassword -V / declare exchange name=exchange1 type=direct diff --git a/connect/connect-rabbitmq-source/rabbitmq-source-ssl.sh b/connect/connect-rabbitmq-source/rabbitmq-source-ssl.sh index 90db1df75c..b4900ddbe1 100755 --- a/connect/connect-rabbitmq-source/rabbitmq-source-ssl.sh +++ b/connect/connect-rabbitmq-source/rabbitmq-source-ssl.sh @@ -12,7 +12,10 @@ cd - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext-ssl.yml" -sleep 5 +playground container exec --command "chown rabbitmq:rabbitmq /tmp/*" --container rabbitmq +playground container restart --container rabbitmq + +sleep 10 log "Send message to RabbitMQ in myqueue" docker exec rabbitmq_producer bash -c "python /producer.py myqueue 5" diff --git a/reproduction-models b/reproduction-models index 4c3704b920..94f1746905 160000 --- a/reproduction-models +++ b/reproduction-models @@ -1 +1 @@ -Subproject commit 4c3704b920973dc5a677b6f7b84a49004031f0ac +Subproject commit 94f1746905e8da917a820891ffb0e6c76c70eaee From 1accc32b853f02beba34d90418675b64f9e1e851 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 20 Dec 2024 09:25:16 +0100 Subject: [PATCH 106/659] wip --- secrets.tar.gpg | Bin 7795 -> 7799 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/secrets.tar.gpg b/secrets.tar.gpg index 9189ba3e7a225ec94ea541d0fa3494190f2b00b6..db2ac53d94bfcdf453edb49bf282930697883296 100644 GIT binary patch literal 7799 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 J=`a{q(-u16{QUp` literal 7795 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 F!UJ-1QtSW# From f6c812250ef3efa7b42394d0a7fa90ca7a43b6a1 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 20 Dec 2024 14:44:15 +0100 Subject: [PATCH 107/659] wip --- .github/workflows/update-readme.yml | 46 +++++++------ scripts/cli/docs/cli-template.md | 56 ++++++++++++++++ scripts/cli/playground | 85 +++++++++++++++++++++++++ scripts/cli/src/bashly.yml | 3 + scripts/cli/src/commands/update-docs.sh | 6 ++ 5 files changed, 176 insertions(+), 20 deletions(-) create mode 100644 scripts/cli/docs/cli-template.md create mode 100644 scripts/cli/src/commands/update-docs.sh diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml index 0fd4a7efb6..9d61e09a80 100644 --- a/.github/workflows/update-readme.yml +++ b/.github/workflows/update-readme.yml @@ -17,34 +17,40 @@ jobs: ssh-key: ${{ secrets.GH_SSH_KEY_FILE }} ssh-strict: 'false' - - name: Update README + - name: Update DOCS run: | + gem install bashly cd ./scripts/cli - ./playground update-readme --tags "7.6.1" - env: - GH_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }} - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} - AWS_REGION: ${{ secrets.AWS_REGION}} + ./playground update-docs - - name: Pushes content.md - uses: dmnemec/copy_file_to_another_repo_action@main - env: - API_TOKEN_GITHUB: ${{ secrets.CI_GITHUB_TOKEN }} - with: - source_file: './docs/content.md' - destination_repo: 'vdesabou/kafka-docker-playground-docs' - destination_folder: 'docs' - user_email: 'vincent.desaboulin@gmail.com' - user_name: 'vdesabou' - commit_message: 'updating with latest versions' + # - name: Update README + # run: | + # cd ./scripts/cli + # ./playground update-readme --tags "7.6.1" + # env: + # GH_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }} + # AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} + # AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} + # AWS_REGION: ${{ secrets.AWS_REGION}} + + # - name: Pushes content.md + # uses: dmnemec/copy_file_to_another_repo_action@main + # env: + # API_TOKEN_GITHUB: ${{ secrets.CI_GITHUB_TOKEN }} + # with: + # source_file: './docs/content.md' + # destination_repo: 'vdesabou/kafka-docker-playground-docs' + # destination_folder: 'docs' + # user_email: 'vincent.desaboulin@gmail.com' + # user_name: 'vdesabou' + # commit_message: 'updating with latest versions' - - name: Pushes introduction.md + - name: Pushes docs uses: dmnemec/copy_file_to_another_repo_action@main env: API_TOKEN_GITHUB: ${{ secrets.CI_GITHUB_TOKEN }} with: - source_file: './docs/introduction.md' + source_file: './docs' destination_repo: 'vdesabou/kafka-docker-playground-docs' destination_folder: 'docs' user_email: 'vincent.desaboulin@gmail.com' diff --git a/scripts/cli/docs/cli-template.md b/scripts/cli/docs/cli-template.md new file mode 100644 index 0000000000..5846e39f9b --- /dev/null +++ b/scripts/cli/docs/cli-template.md @@ -0,0 +1,56 @@ +# 🧠 CLI + +`playground` CLI is available in `scripts/cli/playground`. +It makes so much easier to use the playground and reduces a lot the Docker knowledge required ! + +## 🚜 Setup + +### 🦶 Setup PATH + +Add it to your `PATH` environment variable by adding this in your `~/.bashrc` or `~/.zshrc`: + +```bash +export PATH=/path/to/kafka-docker-playground/scripts/cli:$PATH +``` + +> [!WARNING] +> The bash script generated by [bashly](https://bashly.dannyb.co/) can run in any shell, but require that bash 4 or higher is installed. +> Mac users can upgrade bash by running `brew install bash` + +### ⚡ Setup completion + +A Bash completion file is also available in `scripts/cli/completions.bash`. + +In order to be able to use completion with the CLI, you just need to add this in your `~/.bashrc` or `~/.zshrc`: + +```bash +source /path/to/kafka-docker-playground/scripts/cli/completions.bash +``` + +> [!NOTE] +> If you use ZSH, but **not** `Oh-My-Zsh`, please check [this](https://bashly.dannyb.co/advanced/bash-completion/#completions-in-zsh). + +### 🪄 Setup Shell Script Command Completion Visual Studio Code extension + +Get nice [IntelliSense](https://learn.microsoft.com/en-us/visualstudio/ide/using-intellisense?view=vs-2022) completion for `playground` CLI in Visual Studio Code ! It uses a slightly modified version of "Shell Script Command Completion" Visual Studio Code extension (https://marketplace.visualstudio.com/items?itemName=tetradresearch.vscode-h2o): + +![vscode-extension](./images/vscode-extension.gif) + +To install it, follow those 2 steps: + +```bash +playground tools install-vscode-extension +``` + +Once installed, go on a `.sh` script and then type in Palette `Ctrl+Shift+P` (or `⌘+⇧+P` on macOS) and choose `Shell Completion: Load Command Spec (experimental)` and then type `playground` + +![extension](./images/vscode_extension1.jpg) + +![extension](./images/vscode_extension2.jpg) + +### ⚙️ Config + +CLI can be configured using [playground config](/playground%20config) + +## ✨ Command Reference + diff --git a/scripts/cli/playground b/scripts/cli/playground index f8c9596c59..9d164d5df7 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -941,6 +941,27 @@ playground_update_readme_usage() { fi } +# :command.usage +playground_update_docs_usage() { + printf "playground update-docs\n\n" + + printf "%s\n" "$(bold "== Usage ==")" + printf " playground update-docs\n" + printf " playground update-docs --help | -h\n" + echo + + # :command.long_usage + if [[ -n "$long_usage" ]]; then + printf "%s\n" "$(bold "== Options ==")" + + # :command.usage_fixed_flags + printf " %s\n" "$(magenta "--help, -h")" + printf " Show this help\n" + echo + + fi +} + # :command.usage playground_bashly_reload_usage() { printf "playground bashly-reload\n\n" @@ -13356,6 +13377,17 @@ playground_update_readme_command() { } +# :command.function +playground_update_docs_command() { + # src/commands/update-docs.sh + cd ${root_folder}/scripts/cli + + docker run --rm -it --user $(id -u):$(id -g) --volume "$PWD:/app" dannyben/bashly render templates/markdown docs + + cat ${root_folder}scripts/cli/docs/cli-template.md > ${root_folder}/docs/cli.md + cat ${root_folder}/scripts/cli/docs/index.md >> ${root_folder}/docs/cli.md +} + # :command.function playground_bashly_reload_command() { # src/commands/bashly-reload.sh @@ -25669,6 +25701,13 @@ parse_requirements() { shift $# ;; + update-docs) + action="update-docs" + shift + playground_update_docs_parse_requirements "$@" + shift $# + ;; + bashly-reload) action="bashly-reload" shift @@ -27314,6 +27353,51 @@ playground_update_readme_parse_requirements() { } +# :command.parse_requirements +playground_update_docs_parse_requirements() { + # :command.fixed_flags_filter + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + --help | -h) + long_usage=yes + playground_update_docs_usage + exit + ;; + + *) + break + ;; + + esac + done + + # :command.command_filter + action="update-docs" + + # :command.parse_requirements_while + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; + + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + printf "invalid argument: %s\n" "$key" >&2 + exit 1 + + ;; + + esac + done + +} + # :command.parse_requirements playground_bashly_reload_parse_requirements() { # :command.fixed_flags_filter @@ -39598,6 +39682,7 @@ run() { "get-playground-repro-export-with-fzf") playground_get_playground_repro_export_with_fzf_command ;; "get-predefined-schemas") playground_get_predefined_schemas_command ;; "update-readme") playground_update_readme_command ;; + "update-docs") playground_update_docs_command ;; "bashly-reload") playground_bashly_reload_command ;; "state") playground_state_command ;; "state show") playground_state_show_command ;; diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index 59ed7a7847..3b00759d6e 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -240,6 +240,9 @@ commands: - long: --generate-for-kb required: false +- name: update-docs + private: true + - name: bashly-reload private: true dependencies: diff --git a/scripts/cli/src/commands/update-docs.sh b/scripts/cli/src/commands/update-docs.sh new file mode 100644 index 0000000000..cab01e07af --- /dev/null +++ b/scripts/cli/src/commands/update-docs.sh @@ -0,0 +1,6 @@ +cd ${root_folder}/scripts/cli + +docker run --rm -it --user $(id -u):$(id -g) --volume "$PWD:/app" dannyben/bashly render templates/markdown docs + +cat ${root_folder}scripts/cli/docs/cli-template.md > ${root_folder}/docs/cli.md +cat ${root_folder}/scripts/cli/docs/index.md >> ${root_folder}/docs/cli.md \ No newline at end of file From d2a77b837f852cdbab78bae229ef5ee79fa11be3 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 20 Dec 2024 14:48:45 +0100 Subject: [PATCH 108/659] sudo --- .github/workflows/update-readme.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml index 9d61e09a80..f0d78a1c3e 100644 --- a/.github/workflows/update-readme.yml +++ b/.github/workflows/update-readme.yml @@ -19,7 +19,7 @@ jobs: - name: Update DOCS run: | - gem install bashly + sudo gem install bashly cd ./scripts/cli ./playground update-docs @@ -55,4 +55,4 @@ jobs: destination_folder: 'docs' user_email: 'vincent.desaboulin@gmail.com' user_name: 'vdesabou' - commit_message: 'updating with latest versions' \ No newline at end of file + commit_message: 'updating with latest versions' From 60bab3fa06a4a2e153f700d5bca13d57213f4019 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 20 Dec 2024 14:52:21 +0100 Subject: [PATCH 109/659] wip --- scripts/cli/playground | 2 +- scripts/cli/src/commands/update-docs.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 9d164d5df7..d57fc4f051 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -13382,7 +13382,7 @@ playground_update_docs_command() { # src/commands/update-docs.sh cd ${root_folder}/scripts/cli - docker run --rm -it --user $(id -u):$(id -g) --volume "$PWD:/app" dannyben/bashly render templates/markdown docs + docker run --rm -i --user $(id -u):$(id -g) --volume "$PWD:/app" dannyben/bashly render templates/markdown docs cat ${root_folder}scripts/cli/docs/cli-template.md > ${root_folder}/docs/cli.md cat ${root_folder}/scripts/cli/docs/index.md >> ${root_folder}/docs/cli.md diff --git a/scripts/cli/src/commands/update-docs.sh b/scripts/cli/src/commands/update-docs.sh index cab01e07af..613bc98f39 100644 --- a/scripts/cli/src/commands/update-docs.sh +++ b/scripts/cli/src/commands/update-docs.sh @@ -1,6 +1,6 @@ cd ${root_folder}/scripts/cli -docker run --rm -it --user $(id -u):$(id -g) --volume "$PWD:/app" dannyben/bashly render templates/markdown docs +docker run --rm -i --user $(id -u):$(id -g) --volume "$PWD:/app" dannyben/bashly render templates/markdown docs cat ${root_folder}scripts/cli/docs/cli-template.md > ${root_folder}/docs/cli.md cat ${root_folder}/scripts/cli/docs/index.md >> ${root_folder}/docs/cli.md \ No newline at end of file From 7f3142d9e1962a6feafb054b6e427cea272d74ca Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 20 Dec 2024 14:58:15 +0100 Subject: [PATCH 110/659] wip --- scripts/cli/{docs => docs-template}/cli-template.md | 0 scripts/cli/playground | 2 +- scripts/cli/src/commands/update-docs.sh | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename scripts/cli/{docs => docs-template}/cli-template.md (100%) diff --git a/scripts/cli/docs/cli-template.md b/scripts/cli/docs-template/cli-template.md similarity index 100% rename from scripts/cli/docs/cli-template.md rename to scripts/cli/docs-template/cli-template.md diff --git a/scripts/cli/playground b/scripts/cli/playground index d57fc4f051..ab79d2e2eb 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -13384,7 +13384,7 @@ playground_update_docs_command() { docker run --rm -i --user $(id -u):$(id -g) --volume "$PWD:/app" dannyben/bashly render templates/markdown docs - cat ${root_folder}scripts/cli/docs/cli-template.md > ${root_folder}/docs/cli.md + cat ${root_folder}scripts/cli/docs-template/cli-template.md > ${root_folder}/docs/cli.md cat ${root_folder}/scripts/cli/docs/index.md >> ${root_folder}/docs/cli.md } diff --git a/scripts/cli/src/commands/update-docs.sh b/scripts/cli/src/commands/update-docs.sh index 613bc98f39..21dc414d7e 100644 --- a/scripts/cli/src/commands/update-docs.sh +++ b/scripts/cli/src/commands/update-docs.sh @@ -2,5 +2,5 @@ cd ${root_folder}/scripts/cli docker run --rm -i --user $(id -u):$(id -g) --volume "$PWD:/app" dannyben/bashly render templates/markdown docs -cat ${root_folder}scripts/cli/docs/cli-template.md > ${root_folder}/docs/cli.md +cat ${root_folder}scripts/cli/docs-template/cli-template.md > ${root_folder}/docs/cli.md cat ${root_folder}/scripts/cli/docs/index.md >> ${root_folder}/docs/cli.md \ No newline at end of file From 4b46dc7931b50414cb0b00b7525f49975e462531 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 20 Dec 2024 15:06:23 +0100 Subject: [PATCH 111/659] fix --- scripts/cli/playground | 2 +- scripts/cli/src/commands/update-docs.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index ab79d2e2eb..adb89505d2 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -13384,7 +13384,7 @@ playground_update_docs_command() { docker run --rm -i --user $(id -u):$(id -g) --volume "$PWD:/app" dannyben/bashly render templates/markdown docs - cat ${root_folder}scripts/cli/docs-template/cli-template.md > ${root_folder}/docs/cli.md + cat ${root_folder}/scripts/cli/docs-template/cli-template.md > ${root_folder}/docs/cli.md cat ${root_folder}/scripts/cli/docs/index.md >> ${root_folder}/docs/cli.md } diff --git a/scripts/cli/src/commands/update-docs.sh b/scripts/cli/src/commands/update-docs.sh index 21dc414d7e..0c7760d339 100644 --- a/scripts/cli/src/commands/update-docs.sh +++ b/scripts/cli/src/commands/update-docs.sh @@ -2,5 +2,5 @@ cd ${root_folder}/scripts/cli docker run --rm -i --user $(id -u):$(id -g) --volume "$PWD:/app" dannyben/bashly render templates/markdown docs -cat ${root_folder}scripts/cli/docs-template/cli-template.md > ${root_folder}/docs/cli.md +cat ${root_folder}/scripts/cli/docs-template/cli-template.md > ${root_folder}/docs/cli.md cat ${root_folder}/scripts/cli/docs/index.md >> ${root_folder}/docs/cli.md \ No newline at end of file From 185b3df44f698fbe15a1e9a33aa69c1b774a53a9 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 20 Dec 2024 15:10:41 +0100 Subject: [PATCH 112/659] Update update-readme.yml --- .github/workflows/update-readme.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml index f0d78a1c3e..c513b801f0 100644 --- a/.github/workflows/update-readme.yml +++ b/.github/workflows/update-readme.yml @@ -50,7 +50,7 @@ jobs: env: API_TOKEN_GITHUB: ${{ secrets.CI_GITHUB_TOKEN }} with: - source_file: './docs' + source_file: './docs/*.md' destination_repo: 'vdesabou/kafka-docker-playground-docs' destination_folder: 'docs' user_email: 'vincent.desaboulin@gmail.com' From 77d2ee04e53326b9460cda45000e28d04bdb0031 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 20 Dec 2024 15:12:46 +0100 Subject: [PATCH 113/659] Update update-readme.yml --- .github/workflows/update-readme.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml index c513b801f0..d63d4b324b 100644 --- a/.github/workflows/update-readme.yml +++ b/.github/workflows/update-readme.yml @@ -50,9 +50,9 @@ jobs: env: API_TOKEN_GITHUB: ${{ secrets.CI_GITHUB_TOKEN }} with: - source_file: './docs/*.md' + source_file: './docs' destination_repo: 'vdesabou/kafka-docker-playground-docs' - destination_folder: 'docs' + #destination_folder: 'docs' user_email: 'vincent.desaboulin@gmail.com' user_name: 'vdesabou' commit_message: 'updating with latest versions' From 7f74303785ab36b64c82e47162a023d648198e8e Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 20 Dec 2024 16:16:24 +0100 Subject: [PATCH 114/659] wip --- scripts/cli/playground | 2 ++ scripts/cli/src/commands/update-docs.sh | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index adb89505d2..72155e0a08 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -13386,6 +13386,8 @@ playground_update_docs_command() { cat ${root_folder}/scripts/cli/docs-template/cli-template.md > ${root_folder}/docs/cli.md cat ${root_folder}/scripts/cli/docs/index.md >> ${root_folder}/docs/cli.md + + mv ${root_folder}/scripts/cli/docs/* ${root_folder}/docs/ } # :command.function diff --git a/scripts/cli/src/commands/update-docs.sh b/scripts/cli/src/commands/update-docs.sh index 0c7760d339..e45142f3fe 100644 --- a/scripts/cli/src/commands/update-docs.sh +++ b/scripts/cli/src/commands/update-docs.sh @@ -3,4 +3,6 @@ cd ${root_folder}/scripts/cli docker run --rm -i --user $(id -u):$(id -g) --volume "$PWD:/app" dannyben/bashly render templates/markdown docs cat ${root_folder}/scripts/cli/docs-template/cli-template.md > ${root_folder}/docs/cli.md -cat ${root_folder}/scripts/cli/docs/index.md >> ${root_folder}/docs/cli.md \ No newline at end of file +cat ${root_folder}/scripts/cli/docs/index.md >> ${root_folder}/docs/cli.md + +mv ${root_folder}/scripts/cli/docs/* ${root_folder}/docs/ \ No newline at end of file From 1713d91a09ee1b5cbe6ad400996cadd421c910e4 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 20 Dec 2024 16:19:54 +0100 Subject: [PATCH 115/659] wip --- .github/workflows/ci.yml | 23 ++++++++------------- .github/workflows/update-readme.yml | 31 +++++++++-------------------- 2 files changed, 17 insertions(+), 37 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2b6c290b9..a3b5e8f7f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -596,6 +596,12 @@ jobs: SALESFORCE_CONSUMER_KEY_ACCOUNT2: ${{ secrets.SALESFORCE_CONSUMER_KEY_ACCOUNT2}} SALESFORCE_CONSUMER_PASSWORD_ACCOUNT2: ${{ secrets.SALESFORCE_CONSUMER_PASSWORD_ACCOUNT2}} + - name: Update DOCS + run: | + sudo gem install bashly + cd ./scripts/cli + ./playground update-docs + - name: Update README run: | cd ./scripts/cli @@ -606,26 +612,13 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} AWS_REGION: ${{ secrets.AWS_REGION}} - - name: Pushes content.md - uses: dmnemec/copy_file_to_another_repo_action@main - env: - API_TOKEN_GITHUB: ${{ secrets.CI_GITHUB_TOKEN }} - with: - source_file: './docs/content.md' - destination_repo: 'vdesabou/kafka-docker-playground-docs' - destination_folder: 'docs' - user_email: 'vincent.desaboulin@gmail.com' - user_name: 'vdesabou' - commit_message: 'updating with latest versions' - - - name: Pushes introduction.md + - name: Pushes docs uses: dmnemec/copy_file_to_another_repo_action@main env: API_TOKEN_GITHUB: ${{ secrets.CI_GITHUB_TOKEN }} with: - source_file: './docs/introduction.md' + source_file: './docs' destination_repo: 'vdesabou/kafka-docker-playground-docs' - destination_folder: 'docs' user_email: 'vincent.desaboulin@gmail.com' user_name: 'vdesabou' commit_message: 'updating with latest versions' diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml index d63d4b324b..fd6b672131 100644 --- a/.github/workflows/update-readme.yml +++ b/.github/workflows/update-readme.yml @@ -23,27 +23,15 @@ jobs: cd ./scripts/cli ./playground update-docs - # - name: Update README - # run: | - # cd ./scripts/cli - # ./playground update-readme --tags "7.6.1" - # env: - # GH_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }} - # AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} - # AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} - # AWS_REGION: ${{ secrets.AWS_REGION}} - - # - name: Pushes content.md - # uses: dmnemec/copy_file_to_another_repo_action@main - # env: - # API_TOKEN_GITHUB: ${{ secrets.CI_GITHUB_TOKEN }} - # with: - # source_file: './docs/content.md' - # destination_repo: 'vdesabou/kafka-docker-playground-docs' - # destination_folder: 'docs' - # user_email: 'vincent.desaboulin@gmail.com' - # user_name: 'vdesabou' - # commit_message: 'updating with latest versions' + - name: Update README + run: | + cd ./scripts/cli + ./playground update-readme --tags "7.6.1" + env: + GH_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} + AWS_REGION: ${{ secrets.AWS_REGION}} - name: Pushes docs uses: dmnemec/copy_file_to_another_repo_action@main @@ -52,7 +40,6 @@ jobs: with: source_file: './docs' destination_repo: 'vdesabou/kafka-docker-playground-docs' - #destination_folder: 'docs' user_email: 'vincent.desaboulin@gmail.com' user_name: 'vdesabou' commit_message: 'updating with latest versions' From 1cf3f543c53ffd693872743c7be905379a6867db Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 27 Dec 2024 14:43:26 +0100 Subject: [PATCH 116/659] Remove neo4j example #6175 --- .github/workflows/ci.yml | 2 +- connect/connect-neo4j-sink/README.md | 86 ------------------ connect/connect-neo4j-sink/Screenshot1.png | Bin 124453 -> 0 bytes .../contrib.sink.avro.neo4j.json | 14 --- .../docker-compose.plaintext.yml | 25 ----- connect/connect-neo4j-sink/neo4j.sh | 59 ------------ connect/connect-neo4j-sink/stop.sh | 8 -- docs/content-template.md | 1 - reproduction-models | 2 +- 9 files changed, 2 insertions(+), 195 deletions(-) delete mode 100644 connect/connect-neo4j-sink/README.md delete mode 100644 connect/connect-neo4j-sink/Screenshot1.png delete mode 100644 connect/connect-neo4j-sink/contrib.sink.avro.neo4j.json delete mode 100644 connect/connect-neo4j-sink/docker-compose.plaintext.yml delete mode 100755 connect/connect-neo4j-sink/neo4j.sh delete mode 100755 connect/connect-neo4j-sink/stop.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a3b5e8f7f7..602b69355b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,7 +111,7 @@ jobs: "🚀 connect/connect-jms-tibco-sink connect/connect-jms-tibco-source connect/connect-debezium-mongodb-source connect/connect-debezium-mysql-source connect/connect-debezium-postgresql-source connect/connect-debezium-sqlserver-source connect/connect-elasticsearch-sink connect/connect-datadiode-source-sink", "🚀 connect/connect-hdfs2-sink connect/connect-hdfs2-source connect/connect-hdfs3-sink connect/connect-hdfs3-source connect/connect-ibm-mq-sink connect/connect-ibm-mq-source connect/connect-snmp-source connect/connect-omnisci-sink", "🚀 connect/connect-cdc-oracle11-source connect/connect-jdbc-oracle11-sink connect/connect-jdbc-oracle11-source connect/connect-influxdb-sink connect/connect-influxdb-source connect/connect-jdbc-mysql-sink connect/connect-jdbc-mysql-source connect/connect-jdbc-postgresql-sink connect/connect-jdbc-postgresql-source connect/connect-jdbc-sqlserver-sink", - "🚀 connect/connect-jdbc-sqlserver-source connect/connect-jdbc-vertica-sink connect/connect-singlestore-sink connect/connect-jdbc-singlestore-source connect/connect-jms-active-mq-source connect/connect-jms-active-mq-sink connect/connect-jms-solace-sink connect/connect-jms-solace-source connect/connect-mongodb-sink connect/connect-mongodb-source connect/connect-mqtt-sink connect/connect-mqtt-source connect/connect-neo4j-sink connect/connect-tibco-sink connect/connect-tibco-source", + "🚀 connect/connect-jdbc-sqlserver-source connect/connect-jdbc-vertica-sink connect/connect-singlestore-sink connect/connect-jdbc-singlestore-source connect/connect-jms-active-mq-source connect/connect-jms-active-mq-sink connect/connect-jms-solace-sink connect/connect-jms-solace-source connect/connect-mongodb-sink connect/connect-mongodb-source connect/connect-mqtt-sink connect/connect-mqtt-source connect/connect-tibco-sink connect/connect-tibco-source", "🚀 connect/connect-jdbc-oracle12-source connect/connect-jdbc-oracle12-sink", "🚀 connect/connect-jdbc-oracle19-source connect/connect-jdbc-oracle19-sink connect/connect-jms-oracle19-sink connect/connect-jms-oracle19-source", "🚀 connect/connect-jdbc-oracle21-source connect/connect-jdbc-oracle21-sink connect/connect-jms-oracle21-sink connect/connect-jms-oracle21-source", diff --git a/connect/connect-neo4j-sink/README.md b/connect/connect-neo4j-sink/README.md deleted file mode 100644 index 0da775e5c8..0000000000 --- a/connect/connect-neo4j-sink/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# Neo4j Sink connector - - - -## Objective - -Quickly test [Neo4j Sink](https://neo4j.com/labs/kafka/4.0/kafka-connect/) connector. - - -## How to run - -Simply run: - -``` -$ just use command and search for neo4j.sh in this folder -``` - -Neo4j UI is available at [127.0.0.1:7474](http://127.0.0.1:7474) `neo4j/connect` - -## Details of what the script is doing - -Sending 1000 messages to topic `my-topic`using [neo4j-streams-sink-tester](https://github.com/conker84/neo4j-streams-sink-tester) - -```bash -$ docker exec connect java -jar /tmp/neo4j-streams-sink-tester-1.0.jar -f AVRO -e 1000 -Dkafka.bootstrap.server=broker:9092 -Dkafka.schema.registry.url=http://schema-registry:8081 -``` - -Creating Neo4j Sink connector - -```bash -$ curl -X PUT \ - -H "Content-Type: application/json" \ - --data @/tmp/contrib.sink.avro.neo4j.json \ - http://localhost:8083/connectors | jq . -``` - -With `contrib.sink.avro.neo4j.json`: - -```json -{ - "topics": "my-topic", - "connector.class": "streams.kafka.connect.sink.Neo4jSinkConnector", - "errors.retry.timeout": "-1", - "errors.retry.delay.max.ms": "1000", - "errors.tolerance": "all", - "errors.log.enable": true, - "errors.log.include.messages": true, - "errors.deadletterqueue.topic.name": "test-error-topic", - "neo4j.server.uri": "bolt://neo4j:7687", - "neo4j.authentication.basic.username": "neo4j", - "neo4j.authentication.basic.password": "connect", - "neo4j.encryption.enabled": false, - "neo4j.topic.cypher.my-topic": "MERGE (p:Person{name: event.name, surname: event.surname, from: 'AVRO'}) MERGE (f:Family{name: event.surname}) MERGE (p)-[:BELONGS_TO]->(f)" -} -``` - -Verify data is present in Neo4j http://127.0.0.1:7474 (neo4j/connect) - -```bash -$ open "http://neo4j:connect@127.0.0.1:7474/" -``` - -You should see: - -![Neo4j](Screenshot1.png) - -With `cypher-shell` CLI: - -```bash -$ docker exec -i neo4j cypher-shell -u neo4j -p connect << EOF -MATCH (n) RETURN n; -EOF -``` - -Results: - -``` -(:Person {name: "Name -196952286", from: "AVRO", surname: "Surname A"}) -(:Person {name: "Name -1950152848", from: "AVRO", surname: "Surname C"}) -(:Person {name: "Name 1062585389", from: "AVRO", surname: "Surname C"}) -(:Person {name: "Name -2126769236", from: "AVRO", surname: "Surname B"}) -(:Person {name: "Name 1974372360", from: "AVRO", surname: "Surname B"}) -(:Person {name: "Name -1285319995", from: "AVRO", surname: "Surname B"}) -``` - -N.B: Control Center is reachable at [http://127.0.0.1:9021](http://127.0.0.1:9021]) diff --git a/connect/connect-neo4j-sink/Screenshot1.png b/connect/connect-neo4j-sink/Screenshot1.png deleted file mode 100644 index ae985ab672e213d9dd17242b17fa217c74953ed6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124453 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≈<=YMoE(%>qS0O{dF{UY^RJV> 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 diff --git a/connect/connect-neo4j-sink/contrib.sink.avro.neo4j.json b/connect/connect-neo4j-sink/contrib.sink.avro.neo4j.json deleted file mode 100644 index 663fe00dc5..0000000000 --- a/connect/connect-neo4j-sink/contrib.sink.avro.neo4j.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "topics": "my-topic", - "connector.class": "streams.kafka.connect.sink.Neo4jSinkConnector", - "errors.retry.timeout": "-1", - "errors.retry.delay.max.ms": "1000", - "errors.tolerance": "all", - "errors.log.enable": true, - "errors.log.include.messages": true, - "neo4j.server.uri": "bolt://neo4j:7687", - "neo4j.authentication.basic.username": "neo4j", - "neo4j.authentication.basic.password": "connect", - "neo4j.encryption.enabled": false, - "neo4j.topic.cypher.my-topic": "MERGE (p:Person{name: event.name, surname: event.surname, from: 'AVRO'}) MERGE (f:Family{name: event.surname}) MERGE (p)-[:BELONGS_TO]->(f)" -} \ No newline at end of file diff --git a/connect/connect-neo4j-sink/docker-compose.plaintext.yml b/connect/connect-neo4j-sink/docker-compose.plaintext.yml deleted file mode 100644 index 36a3294ff1..0000000000 --- a/connect/connect-neo4j-sink/docker-compose.plaintext.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -services: - - neo4j: - image: neo4j:4.4.18-enterprise - hostname: neo4j - container_name: neo4j - ports: - - "7474:7474" - - "7687:7687" - environment: - NEO4J_kafka_zookeeper_connect: zookeeper:2181 - NEO4J_kafka_bootstrap_servers: broker:9092 - NEO4J_AUTH: neo4j/connect - NEO4J_dbms_memory_heap_max__size: 4G - NEO4J_ACCEPT_LICENSE_AGREEMENT: 'yes' - - connect: - depends_on: - - neo4j - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/neo4j-kafka-connect-neo4j - volumes: - - ../../connect/connect-neo4j-sink/neo4j-streams-sink-tester-1.0.jar:/tmp/neo4j-streams-sink-tester-1.0.jar - - ../../connect/connect-neo4j-sink/contrib.sink.avro.neo4j.json:/tmp/contrib.sink.avro.neo4j.json diff --git a/connect/connect-neo4j-sink/neo4j.sh b/connect/connect-neo4j-sink/neo4j.sh deleted file mode 100755 index d3e7cfbfad..0000000000 --- a/connect/connect-neo4j-sink/neo4j.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash -set -e - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -source ${DIR}/../../scripts/utils.sh - -if ! version_gt $TAG_BASE "5.99.99"; then - logwarn "WARN: JDK 11 is required for new versions" - exit 111 -fi - -if [ ! -f ${DIR}/neo4j-streams-sink-tester-1.0.jar ] -then - log "Downloading neo4j-streams-sink-tester-1.0.jar" - wget -q https://github.com/conker84/neo4j-streams-sink-tester/releases/download/1/neo4j-streams-sink-tester-1.0.jar -fi - -if [[ "$OSTYPE" == "darwin"* ]] -then - # workaround for issue on linux, see https://github.com/vdesabou/kafka-docker-playground/issues/851#issuecomment-821151962 - chmod -R a+rw . -else - # on CI, docker is run as runneradmin user, need to use sudo - ls -lrt - sudo chmod -R a+rw . - ls -lrt -fi - -PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} -playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" - -log "Sending 1000 messages to topic my-topic using neo4j-streams-sink-tester" -docker exec connect java -jar /tmp/neo4j-streams-sink-tester-1.0.jar -f AVRO -e 1000 -Dkafka.bootstrap.server=broker:9092 -Dkafka.schema.registry.url=http://schema-registry:8081 - - -log "Creating NEO4J Sink connector" -docker exec connect curl -X PUT \ - -H "Content-Type: application/json" \ - --data @/tmp/contrib.sink.avro.neo4j.json \ - http://localhost:8083/connectors/neo4j-sink/config | jq . - - -sleep 15 - -log "Verify data is present in Neo4j using cypher-shell CLI" -docker exec -i neo4j cypher-shell -u neo4j -p connect << EOF -MATCH (n) RETURN n; -EOF -docker exec -i neo4j cypher-shell -u neo4j -p connect > /tmp/result.log <<-EOF -MATCH (n) RETURN n; -EOF -cat /tmp/result.log -grep "AVRO" /tmp/result.log | grep "Surname A" - -if [ -z "$GITHUB_RUN_NUMBER" ] -then - log "Verify data is present in Neo4j http://localhost:7474 (neo4j/connect), see README" - open "http://localhost:7474/" -fi diff --git a/connect/connect-neo4j-sink/stop.sh b/connect/connect-neo4j-sink/stop.sh deleted file mode 100755 index bab6807da5..0000000000 --- a/connect/connect-neo4j-sink/stop.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - - - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -source ${DIR}/../../scripts/utils.sh - -stop_all "$DIR" \ No newline at end of file diff --git a/docs/content-template.md b/docs/content-template.md index e707975699..b137e4c8f6 100644 --- a/docs/content-template.md +++ b/docs/content-template.md @@ -124,7 +124,6 @@ * [MongoDB Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-mongodb-source) (also with 🔑 SSL) :connect/connect-mongodb-source: * [MQTT Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-mqtt-sink) :connect/connect-mqtt-sink: * [MQTT Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-mqtt-source) :connect/connect-mqtt-source: -* [Neo4j Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-neo4j-sink) :connect/connect-neo4j-sink: * [OmniSci Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-omnisci-sink) :connect/connect-omnisci-sink: * [Oracle 11 CDC Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-cdc-oracle11-source) :connect/connect-cdc-oracle11-source: * [Oracle 12c CDC Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-cdc-oracle12-source) (also with 🔑 SSL and mTLS) :connect/connect-cdc-oracle12-source: diff --git a/reproduction-models b/reproduction-models index 94f1746905..0f480c45d8 160000 --- a/reproduction-models +++ b/reproduction-models @@ -1 +1 @@ -Subproject commit 94f1746905e8da917a820891ffb0e6c76c70eaee +Subproject commit 0f480c45d85c3f3314751616e671921cb04fb065 From 2ef78bd210400abe85be4edd69ce8c28865a8d35 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 8 Jan 2025 12:29:42 +0100 Subject: [PATCH 117/659] repro (due to datetime) --- reproduction-models | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reproduction-models b/reproduction-models index 0f480c45d8..6e1eafd192 160000 --- a/reproduction-models +++ b/reproduction-models @@ -1 +1 @@ -Subproject commit 0f480c45d85c3f3314751616e671921cb04fb065 +Subproject commit 6e1eafd192db686dd3c6d4ce97e631316356a697 From 5d6de6544d37e127ed123654a29af25b8c703b92 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 8 Jan 2025 14:39:57 +0100 Subject: [PATCH 118/659] jcl debug --- .../connect-marketo-source/docker-compose.plaintext.yml | 2 ++ connect/connect-marketo-source/marketo-source.sh | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/connect/connect-marketo-source/docker-compose.plaintext.yml b/connect/connect-marketo-source/docker-compose.plaintext.yml index 31410575ac..7e87a9c7a2 100644 --- a/connect/connect-marketo-source/docker-compose.plaintext.yml +++ b/connect/connect-marketo-source/docker-compose.plaintext.yml @@ -2,5 +2,7 @@ services: connect: + volumes: + - ../../connect/connect-marketo-source/jcl-over-slf4j-2.0.7.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-marketo/lib/jcl-over-slf4j-2.0.7.jar environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-marketo \ No newline at end of file diff --git a/connect/connect-marketo-source/marketo-source.sh b/connect/connect-marketo-source/marketo-source.sh index 2595b8e3f6..eea45f159d 100755 --- a/connect/connect-marketo-source/marketo-source.sh +++ b/connect/connect-marketo-source/marketo-source.sh @@ -4,7 +4,12 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh - +cd ../../connect/connect-marketo-source/ +if [ ! -f jcl-over-slf4j-2.0.7.jar ] +then + wget -q https://repo1.maven.org/maven2/org/slf4j/jcl-over-slf4j/2.0.7/jcl-over-slf4j-2.0.7.jar +fi +cd - MARKETO_ENDPOINT_URL=${MARKETO_ENDPOINT_URL:-$1} MARKETO_CLIENT_ID=${MARKETO_CLIENT_ID:-$2} @@ -62,6 +67,8 @@ else SINCE=$(date -d '3 hour ago' +%Y-%m-%dT%H:%M:%SZ) fi +playground debug log-level set --package "org.apache.http" --level TRACE + log "Creating Marketo Source connector" playground connector create-or-update --connector marketo-source << EOF { From 3e5a339c4b7b524e7bdbbab126a53d353607a7b2 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 8 Jan 2025 15:09:54 +0100 Subject: [PATCH 119/659] org.apache.http not by default --- connect/connect-marketo-source/marketo-source.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connect/connect-marketo-source/marketo-source.sh b/connect/connect-marketo-source/marketo-source.sh index eea45f159d..0221eabcc8 100755 --- a/connect/connect-marketo-source/marketo-source.sh +++ b/connect/connect-marketo-source/marketo-source.sh @@ -67,7 +67,7 @@ else SINCE=$(date -d '3 hour ago' +%Y-%m-%dT%H:%M:%SZ) fi -playground debug log-level set --package "org.apache.http" --level TRACE +# playground debug log-level set --package "org.apache.http" --level TRACE log "Creating Marketo Source connector" playground connector create-or-update --connector marketo-source << EOF From a9e52fbe64c8bc6b225e15a5a5e9e9352e32effe Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 8 Jan 2025 17:16:06 +0100 Subject: [PATCH 120/659] Add CI results when using run command #5527 --- scripts/cli/playground | 122 +++++++++++++++++++++- scripts/cli/src/bashly.yml | 4 + scripts/cli/src/commands/get-ci-result.sh | 40 +++++++ scripts/cli/src/commands/run.sh | 2 +- 4 files changed, 166 insertions(+), 2 deletions(-) create mode 100644 scripts/cli/src/commands/get-ci-result.sh diff --git a/scripts/cli/playground b/scripts/cli/playground index 72155e0a08..a14a485360 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -962,6 +962,27 @@ playground_update_docs_usage() { fi } +# :command.usage +playground_get_ci_result_usage() { + printf "playground get-ci-result - get ci result for current test\n\n" + + printf "%s\n" "$(bold "== Usage ==")" + printf " playground get-ci-result\n" + printf " playground get-ci-result --help | -h\n" + echo + + # :command.long_usage + if [[ -n "$long_usage" ]]; then + printf "%s\n" "$(bold "== Options ==")" + + # :command.usage_fixed_flags + printf " %s\n" "$(magenta "--help, -h")" + printf " Show this help\n" + echo + + fi +} + # :command.usage playground_bashly_reload_usage() { printf "playground bashly-reload\n\n" @@ -13390,6 +13411,52 @@ playground_update_docs_command() { mv ${root_folder}/scripts/cli/docs/* ${root_folder}/docs/ } +# :command.function +playground_get_ci_result_command() { + # src/commands/get-ci-result.sh + test_file=$(playground state get run.test_file) + + if [ ! -f $test_file ] + then + + logerror "File $test_file retrieved from $root_folder/playground.ini does not exist!" + exit 1 + fi + + test_file_directory="$(dirname "${test_file}")" + base1="${test_file_directory##*/}" # connect-cdc-oracle12-source + dir1="${test_file_directory%/*}" #connect + dir2="${dir1##*/}/$base1" # connect/connect-cdc-oracle12-source + + tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) + if [ -z "$PG_VERBOSE_MODE" ] + then + trap 'rm -rf $tmp_dir' EXIT + else + log "🐛📂 not deleting tmp dir $tmp_dir" + fi + + content_file="$tmp_dir/content.md" + curl -s -o $content_file https://raw.githubusercontent.com/vdesabou/kafka-docker-playground-docs/main/docs/content.md + + result_ok="$(grep "$dir2" $content_file | sed -n 's/.*\[CI \(ok\)\].*(\(https[^)]*\)).*/🤖CI status: 🟢 ok\n🔗test url: \2/p')" + result_fail="$(grep "$dir2" $content_file | sed -n 's/.*\[CI \(fail\)\].*(\(https[^)]*\)).*/🤖CI status: 🔴 fail\n🐛 github issue: \2/p')" + result_not_tested="$(grep "$dir2" $content_file | sed -n 's/.*\[not tested\].*/🤖CI status: 🤷‍♂️ not tested/p')" + + # print only result not empty + if [ -n "$result_ok" ]; then + log "$result_ok" + fi + + if [ -n "$result_fail" ]; then + logwarn "$result_fail" + fi + + if [ -n "$result_not_tested" ]; then + log "$result_not_tested" + fi +} + # :command.function playground_bashly_reload_command() { # src/commands/bashly-reload.sh @@ -15129,7 +15196,7 @@ playground_run_command() { increment_cli_metric nb_runs log "🚀 Number of examples ran so far: $(get_cli_metric nb_runs)" - + playground get-ci-result log "####################################################" log "🚀 Executing $filename in dir $test_file_directory" log "####################################################" @@ -25710,6 +25777,13 @@ parse_requirements() { shift $# ;; + get-ci-result) + action="get-ci-result" + shift + playground_get_ci_result_parse_requirements "$@" + shift $# + ;; + bashly-reload) action="bashly-reload" shift @@ -27400,6 +27474,51 @@ playground_update_docs_parse_requirements() { } +# :command.parse_requirements +playground_get_ci_result_parse_requirements() { + # :command.fixed_flags_filter + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + --help | -h) + long_usage=yes + playground_get_ci_result_usage + exit + ;; + + *) + break + ;; + + esac + done + + # :command.command_filter + action="get-ci-result" + + # :command.parse_requirements_while + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; + + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + printf "invalid argument: %s\n" "$key" >&2 + exit 1 + + ;; + + esac + done + +} + # :command.parse_requirements playground_bashly_reload_parse_requirements() { # :command.fixed_flags_filter @@ -39685,6 +39804,7 @@ run() { "get-predefined-schemas") playground_get_predefined_schemas_command ;; "update-readme") playground_update_readme_command ;; "update-docs") playground_update_docs_command ;; + "get-ci-result") playground_get_ci_result_command ;; "bashly-reload") playground_bashly_reload_command ;; "state") playground_state_command ;; "state show") playground_state_show_command ;; diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index 3b00759d6e..88fcd940c6 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -243,6 +243,10 @@ commands: - name: update-docs private: true +- name: get-ci-result + help: get ci result for current test + private: true + - name: bashly-reload private: true dependencies: diff --git a/scripts/cli/src/commands/get-ci-result.sh b/scripts/cli/src/commands/get-ci-result.sh new file mode 100644 index 0000000000..216517c5a0 --- /dev/null +++ b/scripts/cli/src/commands/get-ci-result.sh @@ -0,0 +1,40 @@ +test_file=$(playground state get run.test_file) + +if [ ! -f $test_file ] +then + logerror "File $test_file retrieved from $root_folder/playground.ini does not exist!" + exit 1 +fi + +test_file_directory="$(dirname "${test_file}")" +base1="${test_file_directory##*/}" # connect-cdc-oracle12-source +dir1="${test_file_directory%/*}" #connect +dir2="${dir1##*/}/$base1" # connect/connect-cdc-oracle12-source + +tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) +if [ -z "$PG_VERBOSE_MODE" ] +then + trap 'rm -rf $tmp_dir' EXIT +else + log "🐛📂 not deleting tmp dir $tmp_dir" +fi + +content_file="$tmp_dir/content.md" +curl -s -o $content_file https://raw.githubusercontent.com/vdesabou/kafka-docker-playground-docs/main/docs/content.md + +result_ok="$(grep "$dir2" $content_file | sed -n 's/.*\[CI \(ok\)\].*(\(https[^)]*\)).*/🤖CI status: 🟢 ok\n🔗test url: \2/p')" +result_fail="$(grep "$dir2" $content_file | sed -n 's/.*\[CI \(fail\)\].*(\(https[^)]*\)).*/🤖CI status: 🔴 fail\n🐛 github issue: \2/p')" +result_not_tested="$(grep "$dir2" $content_file | sed -n 's/.*\[not tested\].*/🤖CI status: 🤷‍♂️ not tested/p')" + +# print only result not empty +if [ -n "$result_ok" ]; then + log "$result_ok" +fi + +if [ -n "$result_fail" ]; then + logwarn "$result_fail" +fi + +if [ -n "$result_not_tested" ]; then + log "$result_not_tested" +fi \ No newline at end of file diff --git a/scripts/cli/src/commands/run.sh b/scripts/cli/src/commands/run.sh index 160ef21d09..dac019f8df 100644 --- a/scripts/cli/src/commands/run.sh +++ b/scripts/cli/src/commands/run.sh @@ -1517,7 +1517,7 @@ fi increment_cli_metric nb_runs log "🚀 Number of examples ran so far: $(get_cli_metric nb_runs)" - +playground get-ci-result log "####################################################" log "🚀 Executing $filename in dir $test_file_directory" log "####################################################" From 86e55bba8ee5f29f4aacdce574bdd3d5895d26f2 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 9 Jan 2025 13:26:30 +0100 Subject: [PATCH 121/659] wip --- .github/workflows/create-release.yml | 66 ++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 .github/workflows/create-release.yml diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml new file mode 100644 index 0000000000..a2f29ea4a3 --- /dev/null +++ b/.github/workflows/create-release.yml @@ -0,0 +1,66 @@ + +name: Create Release + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + milestone: + types: [closed] + workflow_dispatch: + inputs: + milestoneId: + description: 'Milestone ID' + required: true + default: '1' + +jobs: + build: + name: Create Release + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + repository: vdesabou/kafka-docker-playground + fetch-depth: 0 + # issues need to be closed to generate release notes + - name: Close issues + id: close_issues + uses: lee-dohm/close-matching-issues@v2 + with: + query: "milestone:${{ github.event.milestone.title }}" + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Create Release Notes + uses: docker://decathlon/release-notes-generator-action:3.1.6 + id: Changelog + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + OUTPUT_FOLDER: temp_release_notes + + - name: Read temp_release_notes/release_file.md + id: read_release_file + uses: juliangruber/read-file-action@v1 + with: + path: ./temp_release_notes/release_file.md + + - name: Update changelog.md + run: | + curl -s -o changelog_orig.md https://raw.githubusercontent.com/vdesabou/kafka-docker-playground-docs/refs/heads/main/docs/changelog.md + + tail -n +2 changelog_orig.md > changelog_tmp.md + + echo "# 📜 Change Log" > ./docs/changelog.md + echo "${{ steps.read_release_file.outputs.content }}" >> ./docs/changelog.md + cat changelog_orig.md >> ./docs/changelog.md + + - name: Pushes docs + uses: dmnemec/copy_file_to_another_repo_action@main + env: + API_TOKEN_GITHUB: ${{ secrets.CI_GITHUB_TOKEN }} + with: + source_file: './docs' + destination_repo: 'vdesabou/kafka-docker-playground-docs' + user_email: 'vincent.desaboulin@gmail.com' + user_name: 'vdesabou' + commit_message: 'updating with milestone ${{ github.event.milestone.title }}' \ No newline at end of file From 5933896bb96f0a6b3fea90abafe010d9e98e44e0 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 9 Jan 2025 13:31:38 +0100 Subject: [PATCH 122/659] uses: Decathlon/release-notes-generator-action@v3.1.6 --- .github/workflows/create-release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index a2f29ea4a3..02efd4cc92 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -32,7 +32,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: Create Release Notes - uses: docker://decathlon/release-notes-generator-action:3.1.6 + uses: Decathlon/release-notes-generator-action@v3.1.6 id: Changelog env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -63,4 +63,4 @@ jobs: destination_repo: 'vdesabou/kafka-docker-playground-docs' user_email: 'vincent.desaboulin@gmail.com' user_name: 'vdesabou' - commit_message: 'updating with milestone ${{ github.event.milestone.title }}' \ No newline at end of file + commit_message: 'updating with milestone ${{ github.event.milestone.title }}' From 6c8b1806e73271c1e4184cdfd38f004d3d112994 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 9 Jan 2025 13:43:24 +0100 Subject: [PATCH 123/659] Update create-release.yml --- .github/workflows/create-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 02efd4cc92..a28676f123 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -52,7 +52,7 @@ jobs: echo "# 📜 Change Log" > ./docs/changelog.md echo "${{ steps.read_release_file.outputs.content }}" >> ./docs/changelog.md - cat changelog_orig.md >> ./docs/changelog.md + cat changelog_tmp.md >> ./docs/changelog.md - name: Pushes docs uses: dmnemec/copy_file_to_another_repo_action@main From 5bde9c54763553e95a142044137648baeb669336 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 9 Jan 2025 13:44:24 +0100 Subject: [PATCH 124/659] USE_MILESTONE_TITLE: "true" --- .github/workflows/create-release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index a28676f123..f381f509f6 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -37,6 +37,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} OUTPUT_FOLDER: temp_release_notes + USE_MILESTONE_TITLE: "true" - name: Read temp_release_notes/release_file.md id: read_release_file From b433f7b91dfd713b77f00410f3c138daf29432a0 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 9 Jan 2025 13:47:05 +0100 Subject: [PATCH 125/659] Update create-release.yml --- .github/workflows/create-release.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index f381f509f6..a28676f123 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -37,7 +37,6 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} OUTPUT_FOLDER: temp_release_notes - USE_MILESTONE_TITLE: "true" - name: Read temp_release_notes/release_file.md id: read_release_file From 8a0c3d94b866b11868034127f8b026759b194a63 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 9 Jan 2025 14:02:17 +0100 Subject: [PATCH 126/659] Create release-notes.yml --- .github/release-notes.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/release-notes.yml diff --git a/.github/release-notes.yml b/.github/release-notes.yml new file mode 100644 index 0000000000..b5f78f9cf1 --- /dev/null +++ b/.github/release-notes.yml @@ -0,0 +1,6 @@ +changelog: + sections: + - title: "Enhancements" + labels: ["enhancement"] + - title: "Bugs" + labels: ["fix"] From b1cb5da95420144c8331172120b500c8704eb95c Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 9 Jan 2025 14:13:20 +0100 Subject: [PATCH 127/659] wip --- .../workflows/{create-release.yml => update-changelogs.yml} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename .github/workflows/{create-release.yml => update-changelogs.yml} (97%) diff --git a/.github/workflows/create-release.yml b/.github/workflows/update-changelogs.yml similarity index 97% rename from .github/workflows/create-release.yml rename to .github/workflows/update-changelogs.yml index a28676f123..91d2373878 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/update-changelogs.yml @@ -1,5 +1,5 @@ -name: Create Release +name: Update Change Logs # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the master branch @@ -51,7 +51,7 @@ jobs: tail -n +2 changelog_orig.md > changelog_tmp.md echo "# 📜 Change Log" > ./docs/changelog.md - echo "${{ steps.read_release_file.outputs.content }}" >> ./docs/changelog.md + echo "${{ steps.read_release_file.outputs.content }}" | sed 's/#/##/g' >> ./docs/changelog.md cat changelog_tmp.md >> ./docs/changelog.md - name: Pushes docs From 3e50d683cbd5356e8566768fc97fe4a464082bf3 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 9 Jan 2025 14:19:50 +0100 Subject: [PATCH 128/659] wip --- .github/workflows/update-changelogs.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/update-changelogs.yml b/.github/workflows/update-changelogs.yml index 91d2373878..886051e567 100644 --- a/.github/workflows/update-changelogs.yml +++ b/.github/workflows/update-changelogs.yml @@ -51,6 +51,10 @@ jobs: tail -n +2 changelog_orig.md > changelog_tmp.md echo "# 📜 Change Log" > ./docs/changelog.md + echo "" >> ./docs/changelog.md + current_month=$(date +"%B %Y") + echo "# ${current_month}" >> ./docs/changelog.md + echo "# ${{ github.event.milestone.title }}" | sed 's/#/##/g' >> ./docs/changelog.md echo "${{ steps.read_release_file.outputs.content }}" | sed 's/#/##/g' >> ./docs/changelog.md cat changelog_tmp.md >> ./docs/changelog.md From ef24fa517ffcf3e889feda2b3263483a5e0761e3 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 9 Jan 2025 14:24:46 +0100 Subject: [PATCH 129/659] Update update-changelogs.yml --- .github/workflows/update-changelogs.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/update-changelogs.yml b/.github/workflows/update-changelogs.yml index 886051e567..c912e9def7 100644 --- a/.github/workflows/update-changelogs.yml +++ b/.github/workflows/update-changelogs.yml @@ -15,7 +15,7 @@ on: jobs: build: - name: Create Release + name: Update Change Logs runs-on: ubuntu-latest steps: - name: Checkout code @@ -53,9 +53,8 @@ jobs: echo "# 📜 Change Log" > ./docs/changelog.md echo "" >> ./docs/changelog.md current_month=$(date +"%B %Y") - echo "# ${current_month}" >> ./docs/changelog.md - echo "# ${{ github.event.milestone.title }}" | sed 's/#/##/g' >> ./docs/changelog.md - echo "${{ steps.read_release_file.outputs.content }}" | sed 's/#/##/g' >> ./docs/changelog.md + echo "## ${current_month}" >> ./docs/changelog.md + echo "${{ steps.read_release_file.outputs.content }}" | sed 's/^#/##/g' >> ./docs/changelog.md cat changelog_tmp.md >> ./docs/changelog.md - name: Pushes docs From 9b4a0a859ddff5b5d0145d1d7fdb867b6a440836 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 9 Jan 2025 14:28:58 +0100 Subject: [PATCH 130/659] Update release-notes.yml --- .github/release-notes.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/release-notes.yml b/.github/release-notes.yml index b5f78f9cf1..289cd0deba 100644 --- a/.github/release-notes.yml +++ b/.github/release-notes.yml @@ -1,6 +1,6 @@ changelog: sections: - - title: "Enhancements" + - title: "🌟 Enhancements" labels: ["enhancement"] - - title: "Bugs" + - title: "🐛 Bugs" labels: ["fix"] From 68b46bbec911d35cf5a8a084b112038325e00500 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 9 Jan 2025 14:51:59 +0100 Subject: [PATCH 131/659] fix for #5695 --- connect/connect-marketo-source/marketo-source.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/connect/connect-marketo-source/marketo-source.sh b/connect/connect-marketo-source/marketo-source.sh index 0221eabcc8..ac25003db5 100755 --- a/connect/connect-marketo-source/marketo-source.sh +++ b/connect/connect-marketo-source/marketo-source.sh @@ -44,14 +44,14 @@ playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker- log "Creating an access token" ACCESS_TOKEN=$(docker exec connect \ - curl -X GET \ + curl -s -X GET \ "${MARKETO_ENDPOINT_URL}/identity/oauth/token?grant_type=client_credentials&client_id=$MARKETO_CLIENT_ID&client_secret=$MARKETO_CLIENT_SECRET" | jq -r .access_token) log "Create one lead to Marketo" LEAD_FIRSTNAME=John_$RANDOM LEAD_LASTNAME=Doe_$RANDOM docker exec connect \ - curl -X POST \ + curl -s -X POST \ "${MARKETO_ENDPOINT_URL}/rest/v1/leads.json?access_token=$ACCESS_TOKEN" \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ @@ -69,6 +69,8 @@ fi # playground debug log-level set --package "org.apache.http" --level TRACE +playground topic create --topic marketo_leads + log "Creating Marketo Source connector" playground connector create-or-update --connector marketo-source << EOF { From 1b76864bb2cfe89c22e27e14ce215194862600e4 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 9 Jan 2025 15:56:34 +0100 Subject: [PATCH 132/659] wip --- scripts/cli/confluent-hub-plugin-list.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index 2874ce6c95..4f0755aa3a 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -102,6 +102,7 @@ confluentinc/kafka-connect-solace-sink confluentinc/kafka-connect-solace-source confluentinc/kafka-connect-splunk-s2s confluentinc/kafka-connect-splunk-source +confluentinc/kafka-connect-spooldir confluentinc/kafka-connect-sqs confluentinc/kafka-connect-syslog confluentinc/kafka-connect-teradata @@ -199,6 +200,7 @@ splunk/kafka-connect-splunk spoudinc/spoud-agoora sqdata/sqdata-connector startree/startree-native-integration +streaming-dev-lab/secured-flow streamsendio/file-chunk-sink streamsendio/file-chunk-source streamsets/streamsets-sdc From 1fefc0348f378ad54ec5b38a55beee974eb9cc1f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 10 Jan 2025 10:03:37 +0100 Subject: [PATCH 133/659] Don't use cache in kafka connect jmx exporter --- .../plaintext/jmx-exporter/kafka_connect.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/environment/plaintext/jmx-exporter/kafka_connect.yml b/environment/plaintext/jmx-exporter/kafka_connect.yml index 5d7ad8bf84..9f39c38997 100644 --- a/environment/plaintext/jmx-exporter/kafka_connect.yml +++ b/environment/plaintext/jmx-exporter/kafka_connect.yml @@ -45,7 +45,6 @@ rules: - pattern: "kafka.connect<>(.+): (.+)" name: "kafka_connect_app_info" value: 1 - cache: true labels: client-id: "$1" $2: "$3" @@ -57,26 +56,22 @@ rules: # kafka.connect:type=connect-metrics,client-id=* - pattern: "kafka.connect<>([^:]+)" name: kafka_connect_$1_$3 - cache: true labels: client_id: $2 # kafka.connect:type=connect-worker-metrics - pattern: "kafka.connect<>([^:]+)" name: kafka_connect_connect_worker_metrics_$1 - cache: true labels: connector: "aggregate" # kafka.connect:type=connect-worker-metrics,connector=* - pattern: "kafka.connect<>([^:]+)" name: kafka_connect_connect_worker_metrics_$2 - cache: true labels: connector: $1 # kafka.connect:type=connector-metrics,connector=* - pattern: "kafka.connect<>(.+): (.+)" value: 1 name: kafka_connect_connector_metrics - cache: true labels: connector: $1 $2: $3 @@ -123,7 +118,6 @@ rules: # mbean = com.mongodb.kafka.connect:connector=mongodb-source,task=source-task-0,type=source-task-metrics: - pattern: "com.mongodb.kafka.connect<>(.+): (.+)" name: kafka_connect_mongodb_$1_task_metrics_$4 - cache: true labels: connector: "$2" task: "$3" @@ -133,7 +127,6 @@ rules: # kafka.connect:type=connector-task-metrics,connector=*,task=* - pattern: "kafka.connect<>(.+): (.+)" name: kafka_connect_$1_task_metrics_$4 - cache: true labels: connector: "$2" task: "$3" @@ -141,14 +134,12 @@ rules: # kafka.connect:type=task-error-metrics,connector=*,task=* - pattern: "kafka.connect<>([^:]+)" name: kafka_connect_task_error_metrics_$3 - cache: true labels: connector: "$1" task: "$2" # confluent.replicator:type=confluent-replicator-task-metrics,* : confluent-replicator-task-topic-partition-*: Number Values - pattern: "confluent.replicator<>confluent-replicator-task-topic-partition-(.*): (.*)" name: confluent_replicator_task_metrics_$9 - cache: true labels: $1: "$2" $3: "$4" @@ -158,7 +149,6 @@ rules: - pattern: "confluent.replicator<>(confluent-replicator-destination-cluster|confluent-replicator-source-cluster|confluent-replicator-destination-topic-name): (.*)" name: confluent_replicator_task_metrics_info value: 1 - cache: true labels: $1: "$2" $3: "$4" @@ -170,7 +160,6 @@ rules: - pattern: "kafka.(.+)<>(.+): (.+)" value: 1 name: kafka_$1_app_info - cache: true labels: client_type: $1 client_id: $2 @@ -182,7 +171,6 @@ rules: - pattern: "kafka.(.+)<>(.+):" name: kafka_$1_$2_$9 type: GAUGE - cache: true labels: client_type: $1 $3: "$4" @@ -195,7 +183,6 @@ rules: - pattern: "kafka.(.+)<>(.+):" name: kafka_$1_$2_$7 type: GAUGE - cache: true labels: client_type: $1 $3: "$4" @@ -206,12 +193,10 @@ rules: - pattern: "kafka.(.+)<>(.+):" name: kafka_$1_$2_$5 type: GAUGE - cache: true labels: client_type: $1 $3: "$4" - pattern: "kafka.(.+)<>(.+):" name: kafka_$1_$2_$3 - cache: true labels: client_type: $1 From f0040d295c427729dedc71b044067334330e9c0b Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 10 Jan 2025 11:11:25 +0100 Subject: [PATCH 134/659] Allow to override all CP images #6187 --- ...docker-compose-connect-onprem-to-cloud.yml | 4 +- ccloud/environment/docker-compose.yml | 4 +- .../mirrormaker2/docker-compose.plaintext.yml | 4 +- ...ect-onprem-to-cloud-with-sr-basic-auth.yml | 4 +- ...docker-compose-connect-onprem-to-cloud.yml | 4 +- ...ompose-executable-onprem-to-cloud-avro.yml | 4 +- ...ker-compose-executable-onprem-to-cloud.yml | 4 +- .../docker-compose.yml | 2 +- .../schema-registry-security-plugin/README.md | 2 +- .../docker-compose.yml | 2 +- environment/mdc-plaintext/docker-compose.yml | 12 ++-- environment/plaintext/docker-compose.yml | 8 +-- .../docker-compose.mdc-plaintext.yml | 4 +- .../docker-compose.mdc-plaintext.yml | 4 +- .../docker-compose.rbac-sasl-plain.yml | 2 +- other/rebalancer/docker-compose.yml | 4 +- .../docker-compose.2way-ssl.yml | 2 +- .../docker-compose.sasl-plain.yml | 2 +- .../docker-compose.sasl-ssl.yml | 2 +- scripts/utils.sh | 65 +++++++++++++++++-- .../docker-compose.yml | 2 +- .../docker-compose.yml | 4 +- 22 files changed, 99 insertions(+), 46 deletions(-) diff --git a/ccloud/connect-centralized-license/docker-compose-connect-onprem-to-cloud.yml b/ccloud/connect-centralized-license/docker-compose-connect-onprem-to-cloud.yml index c8a7dd0d6f..7d736568f4 100644 --- a/ccloud/connect-centralized-license/docker-compose-connect-onprem-to-cloud.yml +++ b/ccloud/connect-centralized-license/docker-compose-connect-onprem-to-cloud.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper container_name: zookeeper environment: @@ -36,7 +36,7 @@ services: KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 schema-registry: - image: confluentinc/cp-schema-registry:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/ccloud/environment/docker-compose.yml b/ccloud/environment/docker-compose.yml index bbc04df1c6..33b93541ef 100644 --- a/ccloud/environment/docker-compose.yml +++ b/ccloud/environment/docker-compose.yml @@ -69,7 +69,7 @@ services: CONNECT_LOG4J_APPENDER_STDOUT_LAYOUT_CONVERSIONPATTERN: "[%d] %p %X{connector.context}%m (%c:%L)%n" control-center: - image: confluentinc/cp-enterprise-control-center:${TAG} + image: ${CP_CONTROL_CENTER_IMAGE}:${TAG} hostname: control-center container_name: control-center depends_on: @@ -142,7 +142,7 @@ services: # 75147 # schema-registry: - # image: confluentinc/cp-schema-registry:${TAG} + # image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} # hostname: schema-registry # container_name: schema-registry # ports: diff --git a/ccloud/mirrormaker2/docker-compose.plaintext.yml b/ccloud/mirrormaker2/docker-compose.plaintext.yml index db85e40397..2119e1bb14 100644 --- a/ccloud/mirrormaker2/docker-compose.plaintext.yml +++ b/ccloud/mirrormaker2/docker-compose.plaintext.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper container_name: zookeeper environment: @@ -62,7 +62,7 @@ services: KAFKA_MESSAGE_MAX_BYTES: 10048588 schema-registry: - image: confluentinc/cp-schema-registry:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/ccloud/replicator/docker-compose-connect-onprem-to-cloud-with-sr-basic-auth.yml b/ccloud/replicator/docker-compose-connect-onprem-to-cloud-with-sr-basic-auth.yml index 93c7d28885..1d866cd26c 100644 --- a/ccloud/replicator/docker-compose-connect-onprem-to-cloud-with-sr-basic-auth.yml +++ b/ccloud/replicator/docker-compose-connect-onprem-to-cloud-with-sr-basic-auth.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper container_name: zookeeper environment: @@ -36,7 +36,7 @@ services: KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 schema-registry: - image: confluentinc/cp-schema-registry:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/ccloud/replicator/docker-compose-connect-onprem-to-cloud.yml b/ccloud/replicator/docker-compose-connect-onprem-to-cloud.yml index ae804ceb21..a0f3ef1208 100644 --- a/ccloud/replicator/docker-compose-connect-onprem-to-cloud.yml +++ b/ccloud/replicator/docker-compose-connect-onprem-to-cloud.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper container_name: zookeeper environment: @@ -36,7 +36,7 @@ services: KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 schema-registry: - image: confluentinc/cp-schema-registry:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/ccloud/replicator/docker-compose-executable-onprem-to-cloud-avro.yml b/ccloud/replicator/docker-compose-executable-onprem-to-cloud-avro.yml index 75ccf6bca4..96d1ea4ee8 100644 --- a/ccloud/replicator/docker-compose-executable-onprem-to-cloud-avro.yml +++ b/ccloud/replicator/docker-compose-executable-onprem-to-cloud-avro.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper container_name: zookeeper environment: @@ -36,7 +36,7 @@ services: KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 schema-registry: - image: confluentinc/cp-schema-registry:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/ccloud/replicator/docker-compose-executable-onprem-to-cloud.yml b/ccloud/replicator/docker-compose-executable-onprem-to-cloud.yml index 75ccf6bca4..96d1ea4ee8 100644 --- a/ccloud/replicator/docker-compose-executable-onprem-to-cloud.yml +++ b/ccloud/replicator/docker-compose-executable-onprem-to-cloud.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper container_name: zookeeper environment: @@ -36,7 +36,7 @@ services: KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 schema-registry: - image: confluentinc/cp-schema-registry:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/ccloud/rest-proxy-security-plugin/docker-compose.yml b/ccloud/rest-proxy-security-plugin/docker-compose.yml index 960caa1e47..7bef9bf755 100644 --- a/ccloud/rest-proxy-security-plugin/docker-compose.yml +++ b/ccloud/rest-proxy-security-plugin/docker-compose.yml @@ -2,7 +2,7 @@ services: restproxy: - image: confluentinc/cp-kafka-rest:${TAG} + image: ${CP_REST_PROXY_IMAGE}:${TAG} restart: always hostname: restproxy container_name: restproxy diff --git a/ccloud/schema-registry-security-plugin/README.md b/ccloud/schema-registry-security-plugin/README.md index f1705a6661..ad762375e8 100644 --- a/ccloud/schema-registry-security-plugin/README.md +++ b/ccloud/schema-registry-security-plugin/README.md @@ -24,7 +24,7 @@ Confluent Schema Registry Security Plugin is configured with `JETTY_AUTH` ```yml schema-registry: - image: confluentinc/cp-schema-registry:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/ccloud/schema-registry-security-plugin/docker-compose.yml b/ccloud/schema-registry-security-plugin/docker-compose.yml index 9e3fd6c8a5..b778782dd6 100644 --- a/ccloud/schema-registry-security-plugin/docker-compose.yml +++ b/ccloud/schema-registry-security-plugin/docker-compose.yml @@ -2,7 +2,7 @@ services: schema-registry: - image: confluentinc/cp-schema-registry:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/environment/mdc-plaintext/docker-compose.yml b/environment/mdc-plaintext/docker-compose.yml index a8e088ac39..eb6d6dfd75 100644 --- a/environment/mdc-plaintext/docker-compose.yml +++ b/environment/mdc-plaintext/docker-compose.yml @@ -8,7 +8,7 @@ services: #### zookeeper-europe: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper-europe container_name: zookeeper-europe environment: @@ -16,7 +16,7 @@ services: ZOOKEEPER_TICK_TIME: 2000 zookeeper-us: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper-us container_name: zookeeper-us environment: @@ -24,7 +24,7 @@ services: ZOOKEEPER_TICK_TIME: 2000 zookeeper-metrics: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper-metrics container_name: zookeeper-metrics environment: @@ -199,7 +199,7 @@ services: - ../../confluent-hub:/usr/share/confluent-hub-components schema-registry-europe: - image: confluentinc/cp-schema-registry:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} hostname: schema-registry-europe container_name: schema-registry-europe restart: always @@ -213,7 +213,7 @@ services: SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: broker-europe:9092 schema-registry-us: - image: confluentinc/cp-schema-registry:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} hostname: schema-registry-us container_name: schema-registry-us restart: always @@ -227,7 +227,7 @@ services: SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: broker-us:9092 control-center: - image: confluentinc/cp-enterprise-control-center:${TAG} + image: ${CP_CONTROL_CENTER_IMAGE}:${TAG} hostname: control-center container_name: control-center depends_on: diff --git a/environment/plaintext/docker-compose.yml b/environment/plaintext/docker-compose.yml index a0d460181b..5c27d96233 100644 --- a/environment/plaintext/docker-compose.yml +++ b/environment/plaintext/docker-compose.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper container_name: zookeeper restart: always @@ -148,7 +148,7 @@ services: schema-registry: - image: confluentinc/cp-schema-registry:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} hostname: schema-registry container_name: schema-registry restart: always @@ -441,7 +441,7 @@ services: tty: true control-center: - image: confluentinc/cp-enterprise-control-center:${TAG} + image: ${CP_CONTROL_CENTER_IMAGE}:${TAG} hostname: control-center container_name: control-center restart: always @@ -480,7 +480,7 @@ services: #CONTROL_CENTER_MODE_ENABLE: management # CONTROL_CENTER_ID: 32 rest-proxy: - image: confluentinc/cp-kafka-rest:${TAG} + image: ${CP_REST_PROXY_IMAGE}:${TAG} hostname: rest-proxy container_name: rest-proxy restart: always diff --git a/other/monitoring-cluster-linking/docker-compose.mdc-plaintext.yml b/other/monitoring-cluster-linking/docker-compose.mdc-plaintext.yml index d533987e12..c77d3d4354 100644 --- a/other/monitoring-cluster-linking/docker-compose.mdc-plaintext.yml +++ b/other/monitoring-cluster-linking/docker-compose.mdc-plaintext.yml @@ -2,7 +2,7 @@ services: zookeeper-europe: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper-europe container_name: zookeeper-europe restart: always @@ -17,7 +17,7 @@ services: EXTRA_ARGS: "-javaagent:/usr/share/jmx_exporter/jmx_prometheus_javaagent-0.16.1.jar=1234:/usr/share/jmx_exporter/zookeeper.yml" zookeeper-us: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper-us container_name: zookeeper-us restart: always diff --git a/other/monitoring-demo/docker-compose.mdc-plaintext.yml b/other/monitoring-demo/docker-compose.mdc-plaintext.yml index 2d0a69c8cc..44b33e3910 100644 --- a/other/monitoring-demo/docker-compose.mdc-plaintext.yml +++ b/other/monitoring-demo/docker-compose.mdc-plaintext.yml @@ -10,7 +10,7 @@ services: - ../../other/monitoring-demo/jmx-exporter:/usr/share/jmx_exporter/ zookeeper-europe2: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper-europe2 container_name: zookeeper-europe2 environment: @@ -35,7 +35,7 @@ services: - ../../other/monitoring-demo/jmx-exporter:/usr/share/jmx_exporter/ zookeeper-us2: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper-us2 container_name: zookeeper-us2 environment: diff --git a/other/rbac-with-sr-basic-auth-acl/docker-compose.rbac-sasl-plain.yml b/other/rbac-with-sr-basic-auth-acl/docker-compose.rbac-sasl-plain.yml index a36d7c86ae..dff441f187 100644 --- a/other/rbac-with-sr-basic-auth-acl/docker-compose.rbac-sasl-plain.yml +++ b/other/rbac-with-sr-basic-auth-acl/docker-compose.rbac-sasl-plain.yml @@ -31,7 +31,7 @@ services: - ../../other/rbac-with-sr-basic-auth-acl/scripts/create-acls.sh:/tmp/create-acls.sh schema-registry2: - image: confluentinc/cp-schema-registry:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} hostname: schema-registry2 container_name: schema-registry2 restart: always diff --git a/other/rebalancer/docker-compose.yml b/other/rebalancer/docker-compose.yml index b45fb5218f..0bf708a2c6 100644 --- a/other/rebalancer/docker-compose.yml +++ b/other/rebalancer/docker-compose.yml @@ -1,7 +1,7 @@ --- services: zookeeper: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper container_name: zookeeper environment: @@ -98,7 +98,7 @@ services: control-center: - image: confluentinc/cp-enterprise-control-center:${TAG} + image: ${CP_CONTROL_CENTER_IMAGE}:${TAG} hostname: control-center container_name: control-center depends_on: diff --git a/other/rest-proxy-security-plugin/docker-compose.2way-ssl.yml b/other/rest-proxy-security-plugin/docker-compose.2way-ssl.yml index d56970b79f..a4a3380ea9 100644 --- a/other/rest-proxy-security-plugin/docker-compose.2way-ssl.yml +++ b/other/rest-proxy-security-plugin/docker-compose.2way-ssl.yml @@ -8,7 +8,7 @@ services: KAFKA_LOG4J_LOGGERS: "kafka.authorizer.logger=INFO" restproxy: - image: confluentinc/cp-kafka-rest:${TAG} + image: ${CP_REST_PROXY_IMAGE}:${TAG} restart: always depends_on: - zookeeper diff --git a/other/rest-proxy-security-plugin/docker-compose.sasl-plain.yml b/other/rest-proxy-security-plugin/docker-compose.sasl-plain.yml index 4e5bae4cca..eaf82f3894 100644 --- a/other/rest-proxy-security-plugin/docker-compose.sasl-plain.yml +++ b/other/rest-proxy-security-plugin/docker-compose.sasl-plain.yml @@ -20,7 +20,7 @@ services: user_client="client-secret"; restproxy: - image: confluentinc/cp-kafka-rest:${TAG} + image: ${CP_REST_PROXY_IMAGE}:${TAG} restart: always depends_on: - zookeeper diff --git a/other/rest-proxy-security-plugin/docker-compose.sasl-ssl.yml b/other/rest-proxy-security-plugin/docker-compose.sasl-ssl.yml index 611ac88a0e..b57d4ad0a4 100644 --- a/other/rest-proxy-security-plugin/docker-compose.sasl-ssl.yml +++ b/other/rest-proxy-security-plugin/docker-compose.sasl-ssl.yml @@ -8,7 +8,7 @@ services: KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND: "true" restproxy: - image: confluentinc/cp-kafka-rest:${TAG} + image: ${CP_REST_PROXY_IMAGE}:${TAG} restart: always depends_on: - zookeeper diff --git a/scripts/utils.sh b/scripts/utils.sh index b139e124ff..cdee9ddb93 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -44,17 +44,49 @@ then log "🎓 Use --tag option to specify different version, see https://kafka-docker-playground.io/#/how-to-use?id=🎯-for-confluent-platform-cp" fi fi - export CP_KAFKA_IMAGE=confluentinc/cp-server export CP_BASE_IMAGE=confluentinc/cp-base-new - export CP_KSQL_IMAGE=confluentinc/cp-ksqldb-server - export CP_KSQL_CLI_IMAGE=confluentinc/cp-ksqldb-cli:latest export LEGACY_CONNECT_VALUE_CONVERTER_SCHEMA_REGISTRY_SSL="" export CONNECT_USER="appuser" + if [ -z "$CP_ZOOKEEPER_IMAGE" ] + then + export CP_ZOOKEEPER_IMAGE=confluentinc/cp-zookeeper + fi + + if [ -z "$CP_KAFKA_IMAGE" ] + then + export CP_KAFKA_IMAGE=confluentinc/cp-server + fi + if [ -z "$CP_CONNECT_IMAGE" ] then export CP_CONNECT_IMAGE=confluentinc/cp-server-connect-base fi + + if [ -z "$CP_SCHEMA_REGISTRY_IMAGE" ] + then + export CP_SCHEMA_REGISTRY_IMAGE=confluentinc/cp-schema-registry + fi + + if [ -z "$CP_CONTROL_CENTER_IMAGE" ] + then + export CP_CONTROL_CENTER_IMAGE=confluentinc/cp-enterprise-control-center + fi + + if [ -z "$CP_REST_PROXY_IMAGE" ] + then + export CP_REST_PROXY_IMAGE=confluentinc/cp-kafka-rest + fi + + if [ -z "$CP_KSQL_IMAGE" ] + then + export CP_KSQL_IMAGE=confluentinc/cp-ksqldb-server + fi + + if [ -z "$CP_KSQL_CLI_IMAGE" ] + then + export CP_KSQL_CLI_IMAGE=confluentinc/cp-ksqldb-cli:latest + fi set_kafka_client_tag else if [ -z "$CP_KAFKA_IMAGE" ] @@ -71,13 +103,22 @@ else if version_gt $first_version $second_version; then if [ "$first_version" = "5.3.6" ] then - logwarn "Workaround for 5.3.6 image broker, using custom image vdesabou/cp-server !" - export CP_KAFKA_IMAGE=vdesabou/cp-server + if [ -z "$CP_KAFKA_IMAGE" ] + then + logwarn "Workaround for 5.3.6 image broker, using custom image vdesabou/cp-server !" + export CP_KAFKA_IMAGE=vdesabou/cp-server + fi else - export CP_KAFKA_IMAGE=confluentinc/cp-server + if [ -z "$CP_KAFKA_IMAGE" ] + then + export CP_KAFKA_IMAGE=confluentinc/cp-server + fi fi else + if [ -z "$CP_KAFKA_IMAGE" ] + then export CP_KAFKA_IMAGE=confluentinc/cp-enterprise-kafka + fi fi second_version=5.3.99 if version_gt $first_version $second_version; then @@ -87,11 +128,23 @@ else fi second_version=5.4.99 if version_gt $first_version $second_version; then + if [ -z "$CP_KSQL_IMAGE" ] + then export CP_KSQL_IMAGE=confluentinc/cp-ksqldb-server + fi + if [ -z "$CP_KSQL_CLI_IMAGE" ] + then export CP_KSQL_CLI_IMAGE=confluentinc/cp-ksqldb-cli:${TAG_BASE} + fi else + if [ -z "$CP_KSQL_IMAGE" ] + then export CP_KSQL_IMAGE=confluentinc/cp-ksql-server + fi + if [ -z "$CP_KSQL_CLI_IMAGE" ] + then export CP_KSQL_CLI_IMAGE=confluentinc/cp-ksql-cli:${TAG_BASE} + fi fi second_version=5.2.99 if version_gt $first_version $second_version; then diff --git a/troubleshooting/admin-client-issue-when-broker-down/docker-compose.yml b/troubleshooting/admin-client-issue-when-broker-down/docker-compose.yml index fa068cab36..f5b624a326 100644 --- a/troubleshooting/admin-client-issue-when-broker-down/docker-compose.yml +++ b/troubleshooting/admin-client-issue-when-broker-down/docker-compose.yml @@ -12,7 +12,7 @@ services: container_name: adminclient zookeeper: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper container_name: zookeeper environment: diff --git a/troubleshooting/connect-worker-restart-while-broker-down/docker-compose.yml b/troubleshooting/connect-worker-restart-while-broker-down/docker-compose.yml index aad4b1ffd5..7ff496c0a6 100644 --- a/troubleshooting/connect-worker-restart-while-broker-down/docker-compose.yml +++ b/troubleshooting/connect-worker-restart-while-broker-down/docker-compose.yml @@ -11,7 +11,7 @@ services: zookeeper: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper container_name: zookeeper environment: @@ -185,7 +185,7 @@ services: # CONNECT_LOG4J_ROOT_LOGLEVEL: DEBUG control-center: - image: confluentinc/cp-enterprise-control-center:${TAG} + image: ${CP_CONTROL_CENTER_IMAGE}:${TAG} hostname: control-center container_name: control-center depends_on: From c3485d25172956680d15ba217f28417c814791b3 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 10 Jan 2025 11:11:35 +0100 Subject: [PATCH 135/659] Allow to override all CP images #6187 --- .../docker-compose-executable-onprem-to-cloud.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ccloud/migrate-schemas-to-confluent-cloud/docker-compose-executable-onprem-to-cloud.yml b/ccloud/migrate-schemas-to-confluent-cloud/docker-compose-executable-onprem-to-cloud.yml index 59b39469bd..1eb0c003a0 100644 --- a/ccloud/migrate-schemas-to-confluent-cloud/docker-compose-executable-onprem-to-cloud.yml +++ b/ccloud/migrate-schemas-to-confluent-cloud/docker-compose-executable-onprem-to-cloud.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: confluentinc/cp-zookeeper:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${TAG} hostname: zookeeper container_name: zookeeper environment: @@ -36,7 +36,7 @@ services: KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 schema-registry: - image: confluentinc/cp-schema-registry:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} hostname: schema-registry container_name: schema-registry ports: From a0131ef255ed81b590802415d6243d318f13dd16 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 10 Jan 2025 13:50:41 +0100 Subject: [PATCH 136/659] wip --- secrets.tar.gpg | Bin 7799 -> 7833 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/secrets.tar.gpg b/secrets.tar.gpg index db2ac53d94bfcdf453edb49bf282930697883296..b2945197882bff1a706abf86c54c69b2984d0940 100644 GIT binary patch literal 7833 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 J=`a{q(-u16{QUp` From 0d551b937132ed025ead5ab11cbe5b794c7f8073 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 10 Jan 2025 13:51:30 +0100 Subject: [PATCH 137/659] Unable to use admin client to verify the cleanup policy of --- ...nk-confluent-cloud-provider-integration.sh | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100755 ccloud/fm-aws-s3-sink/fully-managed-s3-sink-confluent-cloud-provider-integration.sh diff --git a/ccloud/fm-aws-s3-sink/fully-managed-s3-sink-confluent-cloud-provider-integration.sh b/ccloud/fm-aws-s3-sink/fully-managed-s3-sink-confluent-cloud-provider-integration.sh new file mode 100755 index 0000000000..ec589978c0 --- /dev/null +++ b/ccloud/fm-aws-s3-sink/fully-managed-s3-sink-confluent-cloud-provider-integration.sh @@ -0,0 +1,136 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +S3_PROVIDER_INTEGRATION_ID=${S3_PROVIDER_INTEGRATION_ID:-$1} + +if [ -z "$S3_PROVIDER_INTEGRATION_ID" ] +then + logerror "S3_PROVIDER_INTEGRATION_ID is not set. Export it as environment variable or pass it as argument" + logerror "follow steps in https://docs.confluent.io/cloud/current/connectors/provider-integration/index.html" + exit 1 +fi + + + +if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) +then + logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" + exit 1 +else + if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] + then + log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" + export AWS_ACCESS_KEY_ID + export AWS_SECRET_ACCESS_KEY + else + if [ -f $HOME/.aws/credentials ] + then + logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" + export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) + export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) + fi + fi + if [ -z "$AWS_REGION" ] + then + AWS_REGION=$(aws configure get region | tr '\r' '\n') + if [ "$AWS_REGION" == "" ] + then + logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" + exit 1 + fi + fi +fi + +bootstrap_ccloud_environment + +set +e +playground topic delete --topic s3_topic +sleep 3 +playground topic create --topic s3_topic --nb-partitions 1 +set -e + +AWS_BUCKET_NAME=pg-bucket-${USER} +AWS_BUCKET_NAME=${AWS_BUCKET_NAME//[-.]/} + + +log "Empty bucket <$AWS_BUCKET_NAME/$TAG>, if required" +set +e +if [ "$AWS_REGION" == "us-east-1" ] +then + aws s3api create-bucket --bucket $AWS_BUCKET_NAME --region $AWS_REGION +else + aws s3api create-bucket --bucket $AWS_BUCKET_NAME --region $AWS_REGION --create-bucket-configuration LocationConstraint=$AWS_REGION +fi +set -e +log "Empty bucket <$AWS_BUCKET_NAME>, if required" +set +e +aws s3 rm s3://$AWS_BUCKET_NAME/$TAG --recursive --region $AWS_REGION +set -e + +log "Creating s3_topic topic in Confluent Cloud (auto.create.topics.enable=false)" +set +e +playground topic create --topic s3_topic +set -e + +log "Sending messages to topic s3_topic" +playground topic produce -t s3_topic --nb-messages 1000 --forced-value '{"f1":"value%g"}' << 'EOF' +{ + "type": "record", + "name": "myrecord", + "fields": [ + { + "name": "f1", + "type": "string" + } + ] +} +EOF + +connector_name="S3_SINK_CPI_$USER" +set +e +playground connector delete --connector $connector_name > /dev/null 2>&1 +set -e + +log "Creating fully managed connector" +playground connector create-or-update --connector $connector_name << EOF +{ + "connector.class": "S3_SINK", + "name": "$connector_name", + "kafka.auth.mode": "KAFKA_API_KEY", + "kafka.api.key": "$CLOUD_KEY", + "kafka.api.secret": "$CLOUD_SECRET", + "topics": "s3_topic", + "topics.dir": "$TAG", + "authentication.method":"IAM Roles", + "provider.integration.id":"$S3_PROVIDER_INTEGRATION_ID", + "input.data.format": "AVRO", + "output.data.format": "AVRO", + "s3.bucket.name": "$AWS_BUCKET_NAME", + "s3.region":"$AWS_REGION", + "time.interval" : "HOURLY", + "flush.size": "1000", + "schema.compatibility": "NONE", + "tasks.max" : "1" +} +EOF +wait_for_ccloud_connector_up $connector_name 180 + +sleep 10 + +# log "Listing objects of in S3" +# aws s3api list-objects --bucket "$AWS_BUCKET_NAME" + +log "Getting one of the avro files locally and displaying content with avro-tools" +aws s3 cp --only-show-errors --recursive s3://$AWS_BUCKET_NAME/$TAG/s3_topic /tmp/s3_topic + +cp /tmp/s3_topic/*/*/*/*/s3_topic+0+0000000000.avro /tmp/s3_topic+0+0000000000.avro + +playground tools read-avro-file --file /tmp/s3_topic+0+0000000000.avro | grep value999 + +log "Do you want to delete the fully managed connector $connector_name ?" +check_if_continue + +playground connector delete --connector $connector_name \ No newline at end of file From 233e4f3c4fc768af9ca3d28d75906035b8ca0414 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 10 Jan 2025 13:57:34 +0100 Subject: [PATCH 138/659] wip --- .github/workflows/update-changelogs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-changelogs.yml b/.github/workflows/update-changelogs.yml index c912e9def7..8e4abdd35f 100644 --- a/.github/workflows/update-changelogs.yml +++ b/.github/workflows/update-changelogs.yml @@ -54,7 +54,7 @@ jobs: echo "" >> ./docs/changelog.md current_month=$(date +"%B %Y") echo "## ${current_month}" >> ./docs/changelog.md - echo "${{ steps.read_release_file.outputs.content }}" | sed 's/^#/##/g' >> ./docs/changelog.md + echo "${{ steps.read_release_file.outputs.content }}" | sed 's/^#/##/g' | sed 's/###/####/g' >> ./docs/changelog.md cat changelog_tmp.md >> ./docs/changelog.md - name: Pushes docs From 1f774ddd4b4b8433beba2cf873064760eea4e497 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 10 Jan 2025 14:15:41 +0100 Subject: [PATCH 139/659] Update release-notes.yml --- .github/release-notes.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/release-notes.yml b/.github/release-notes.yml index 289cd0deba..fec3a6f497 100644 --- a/.github/release-notes.yml +++ b/.github/release-notes.yml @@ -2,5 +2,7 @@ changelog: sections: - title: "🌟 Enhancements" labels: ["enhancement"] + - title: "🧠 CLI" + labels: ["cli"] - title: "🐛 Bugs" labels: ["fix"] From f21287e2dd8e482fe2e1a70cc633ca1a80244e8c Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 10 Jan 2025 15:12:43 +0100 Subject: [PATCH 140/659] wip --- secrets.tar.gpg | Bin 7833 -> 7836 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/secrets.tar.gpg b/secrets.tar.gpg index b2945197882bff1a706abf86c54c69b2984d0940..184d381857d8f3df17668e56f48a10f00137d7e5 100644 GIT binary patch literal 7836 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 Date: Fri, 10 Jan 2025 15:47:08 +0100 Subject: [PATCH 141/659] fix --- scripts/utils.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/scripts/utils.sh b/scripts/utils.sh index cdee9ddb93..2cef244458 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -96,6 +96,23 @@ else log "🚀 Using specified CP version $TAG" fi fi + + if [ -z "$CP_ZOOKEEPER_IMAGE" ] + then + export CP_ZOOKEEPER_IMAGE=confluentinc/cp-zookeeper + fi + if [ -z "$CP_SCHEMA_REGISTRY_IMAGE" ] + then + export CP_SCHEMA_REGISTRY_IMAGE=confluentinc/cp-schema-registry + fi + if [ -z "$CP_REST_PROXY_IMAGE" ] + then + export CP_REST_PROXY_IMAGE=confluentinc/cp-kafka-rest + fi + if [ -z "$CP_CONTROL_CENTER_IMAGE" ] + then + export CP_CONTROL_CENTER_IMAGE=confluentinc/cp-enterprise-control-center + fi # to handle ubi8 images export TAG_BASE=$(echo $TAG | cut -d "-" -f1) first_version=${TAG_BASE} From 929e80247065a3a406ff9c20b227b5d67d0d2459 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 13 Jan 2025 08:28:20 +0100 Subject: [PATCH 142/659] Update release-notes.yml --- .github/release-notes.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/release-notes.yml b/.github/release-notes.yml index fec3a6f497..289cd0deba 100644 --- a/.github/release-notes.yml +++ b/.github/release-notes.yml @@ -2,7 +2,5 @@ changelog: sections: - title: "🌟 Enhancements" labels: ["enhancement"] - - title: "🧠 CLI" - labels: ["cli"] - title: "🐛 Bugs" labels: ["fix"] From 18398180b0191883f899f16dcf717bbf3047f982 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 13 Jan 2025 08:58:50 +0100 Subject: [PATCH 143/659] S3_PROVIDER_INTEGRATION_ID --- .github/workflows/ci-environments.yml | 389 -------------------------- .github/workflows/ci-self-managed.yml | 1 + .github/workflows/ci.yml | 2 + 3 files changed, 3 insertions(+), 389 deletions(-) delete mode 100644 .github/workflows/ci-environments.yml diff --git a/.github/workflows/ci-environments.yml b/.github/workflows/ci-environments.yml deleted file mode 100644 index af1e255269..0000000000 --- a/.github/workflows/ci-environments.yml +++ /dev/null @@ -1,389 +0,0 @@ -name: CI with environments - -on: - # push: - # branches: - # - master - - # schedule: - # - cron: '0 18 * * *' # every day at 6 pm - - workflow_dispatch: - inputs: - test_name: - description: 'test(s) to run (example connect/connect-jms-weblogic-sink connect/connect-http-sink)' - required: false - default: '' - -jobs: - pre-build: - if: ${{ github.event.inputs.test_name == '' }} - name: Cleanup resources - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - repository: vdesabou/kafka-docker-playground - fetch-depth: 0 - - build: - if: ${{ github.event.inputs.test_name == '' }} - runs-on: ubuntu-latest - needs: pre-build - name: ${{ matrix.environment }} ${{ matrix.test_list }} - strategy: - fail-fast: false - matrix: - tag: ["7.5.3"] - #environment: ["ccloud", "sasl-ssl", "sasl-plain", "2way-ssl", "sasl-scram", "kraft-external-plaintext", "kraft-plaintext", "kerberos", "ssl_kerberos", "ldap-authorizer-sasl-plain", "ldap-sasl-plain"] - environment: [ "2way-ssl", "ssl_kerberos"] - test_list : [ - "🚀 connect/connect-active-mq-sink connect/connect-debezium-sqlserver-source connect/connect-http-sink" - ] - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - repository: vdesabou/kafka-docker-playground - fetch-depth: 0 - - - name: "Free up disk space" - run: | - df -h - sudo apt-get -qq purge build-essential ghc* - sudo apt-get clean - sudo apt-get install expect fzf coreutils -y - docker system prune -af - sudo rm -rf /usr/share/dotnet - sudo rm -rf /opt/ghc - sudo rm -rf "/usr/local/share/boost" - sudo rm -rf "$AGENT_TOOLSDIRECTORY" - - sudo docker rmi $(docker image ls -aq) >/dev/null 2>&1 || true - sudo rm -rf \ - /usr/share/dotnet /usr/local/lib/android /opt/ghc \ - /usr/local/share/powershell /usr/share/swift /usr/local/.ghcup \ - /usr/lib/jvm || true - echo "some directories deleted" - sudo apt install aptitude -y >/dev/null 2>&1 - sudo aptitude purge aria2 ansible azure-cli shellcheck rpm xorriso zsync \ - esl-erlang firefox gfortran-8 gfortran-9 google-chrome-stable \ - google-cloud-sdk imagemagick \ - libmagickcore-dev libmagickwand-dev libmagic-dev ant ant-optional kubectl \ - mercurial apt-transport-https mono-complete libmysqlclient \ - unixodbc-dev yarn chrpath libssl-dev libxft-dev \ - libfreetype6 libfreetype6-dev libfontconfig1 libfontconfig1-dev \ - snmp pollinate libpq-dev postgresql-client powershell ruby-full \ - sphinxsearch subversion mongodb-org azure-cli microsoft-edge-stable \ - -y -f >/dev/null 2>&1 - sudo aptitude purge google-cloud-sdk -f -y >/dev/null 2>&1 - sudo aptitude purge microsoft-edge-stable -f -y >/dev/null 2>&1 || true - sudo apt purge microsoft-edge-stable -f -y >/dev/null 2>&1 || true - sudo aptitude purge '~n ^mysql' -f -y >/dev/null 2>&1 - sudo aptitude purge '~n ^php' -f -y >/dev/null 2>&1 - sudo aptitude purge '~n ^dotnet' -f -y >/dev/null 2>&1 - sudo apt-get autoremove -y >/dev/null 2>&1 - sudo apt-get autoclean -y >/dev/null 2>&1 - echo "some packages purged" - - df -h - - - name: "Install confluent CLI" - run: | - curl -L --http1.1 https://cnfl.io/cli | sudo sh -s -- -b /usr/local/bin - export PATH=$PATH:/usr/local/bin - - - name: Decrypt secrets.tar - run: | - ./.github/scripts/decrypt_secret.sh - tar xvf secrets.tar - rm secrets.tar - mkdir -p $HOME/.aws - mv aws_credentials_with_assuming_iam_role $HOME/.aws/credentials-with-assuming-iam-role - mv aws_credentials_aws_account_with_assume_role $HOME/.aws/credentials_aws_account_with_assume_role - chmod -R a+rw $HOME/.aws - mkdir -p $HOME/.confluent - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - env: - SECRETS_ENCRYPTION_PASSWORD: ${{ secrets.SECRETS_ENCRYPTION_PASSWORD }} - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME}} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD}} - - - name: Build and Test - run: | - export PATH=$PATH:$GITHUB_WORKSPACE/scripts/cli - bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" "${{ matrix.environment }}" - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} - AWS_REGION: ${{ secrets.AWS_REGION}} - AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID}} - AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY}} - AWS_STS_ROLE_ARN: ${{ secrets.AWS_STS_ROLE_ARN}} - AZ_USER: ${{ secrets.AZ_USER}} - AZ_PASS: ${{ secrets.AZ_PASS}} - AZURE_SUBSCRIPTION_NAME: ${{ secrets.AZURE_SUBSCRIPTION_NAME}} - CONFLUENT_CLOUD_EMAIL: ${{ secrets.CONFLUENT_CLOUD_EMAIL}} - CONFLUENT_CLOUD_PASSWORD: ${{ secrets.CONFLUENT_CLOUD_PASSWORD}} - ENVIRONMENT: ${{ secrets.ENVIRONMENT}} - CLUSTER_NAME: ${{ secrets.CLUSTER_NAME}} - CLUSTER_REGION: ${{ secrets.CLUSTER_REGION}} - CLUSTER_CLOUD: ${{ secrets.CLUSTER_CLOUD}} - CLUSTER_CREDS: ${{ secrets.CLUSTER_CREDS}} - AWS_DATABRICKS_CLUSTER_NAME: ${{ secrets.AWS_DATABRICKS_CLUSTER_NAME}} - AWS_DATABRICKS_CLUSTER_REGION: ${{ secrets.AWS_DATABRICKS_CLUSTER_REGION}} - AWS_DATABRICKS_CLUSTER_CLOUD: ${{ secrets.AWS_DATABRICKS_CLUSTER_CLOUD}} - AWS_DATABRICKS_CLUSTER_CREDS: ${{ secrets.AWS_DATABRICKS_CLUSTER_CREDS}} - GCP_CLUSTER_NAME: ${{ secrets.GCP_CLUSTER_NAME}} - GCP_CLUSTER_REGION: ${{ secrets.GCP_CLUSTER_REGION}} - GCP_CLUSTER_CLOUD: ${{ secrets.GCP_CLUSTER_CLOUD}} - GCP_CLUSTER_CREDS: ${{ secrets.GCP_CLUSTER_CREDS}} - AZURE_CLUSTER_NAME: ${{ secrets.AZURE_CLUSTER_NAME}} - AZURE_CLUSTER_REGION: ${{ secrets.AZURE_CLUSTER_REGION}} - AZURE_CLUSTER_CLOUD: ${{ secrets.AZURE_CLUSTER_CLOUD}} - AZURE_CLUSTER_CREDS: ${{ secrets.AZURE_CLUSTER_CREDS}} - SCHEMA_REGISTRY_CREDS: ${{ secrets.SCHEMA_REGISTRY_CREDS}} - CONFLUENT_LICENSE: ${{ secrets.CONFLUENT_LICENSE}} - SALESFORCE_USERNAME: ${{ secrets.SALESFORCE_USERNAME}} - SALESFORCE_PASSWORD: ${{ secrets.SALESFORCE_PASSWORD}} - SALESFORCE_CONSUMER_KEY: ${{ secrets.SALESFORCE_CONSUMER_KEY}} - SALESFORCE_CONSUMER_PASSWORD: ${{ secrets.SALESFORCE_CONSUMER_PASSWORD}} - SALESFORCE_SECURITY_TOKEN: ${{ secrets.SALESFORCE_SECURITY_TOKEN}} - SALESFORCE_INSTANCE: ${{ secrets.SALESFORCE_INSTANCE}} - SALESFORCE_USERNAME_ACCOUNT2: ${{ secrets.SALESFORCE_USERNAME_ACCOUNT2}} - SALESFORCE_PASSWORD_ACCOUNT2: ${{ secrets.SALESFORCE_PASSWORD_ACCOUNT2}} - SALESFORCE_SECURITY_TOKEN_ACCOUNT2: ${{ secrets.SALESFORCE_SECURITY_TOKEN_ACCOUNT2}} - SALESFORCE_CONSUMER_KEY_ACCOUNT2: ${{ secrets.SALESFORCE_CONSUMER_KEY_ACCOUNT2}} - SALESFORCE_CONSUMER_PASSWORD_ACCOUNT2: ${{ secrets.SALESFORCE_CONSUMER_PASSWORD_ACCOUNT2}} - SALESFORCE_CONSUMER_KEY_WITH_JWT: ${{ secrets.SALESFORCE_CONSUMER_KEY_WITH_JWT}} - SALESFORCE_CONSUMER_PASSWORD_WITH_JWT: ${{ secrets.SALESFORCE_CONSUMER_PASSWORD_WITH_JWT}} - DD_API_KEY: ${{ secrets.DD_API_KEY}} - DD_APP_KEY: ${{ secrets.DD_APP_KEY}} - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME}} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD}} - JIRA_URL: ${{ secrets.JIRA_URL}} - JIRA_USERNAME: ${{ secrets.JIRA_USERNAME}} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN}} - MARKETO_ENDPOINT_URL: ${{ secrets.MARKETO_ENDPOINT_URL}} - MARKETO_CLIENT_ID: ${{ secrets.MARKETO_CLIENT_ID}} - MARKETO_CLIENT_SECRET: ${{ secrets.MARKETO_CLIENT_SECRET}} - PAGERDUTY_USER_EMAIL: ${{ secrets.PAGERDUTY_USER_EMAIL}} - PAGERDUTY_API_KEY: ${{ secrets.PAGERDUTY_API_KEY}} - PAGERDUTY_SERVICE_ID: ${{ secrets.PAGERDUTY_SERVICE_ID}} - CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_KEY: ${{ secrets.CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_KEY}} - CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_SECRET: ${{ secrets.CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_SECRET}} - SERVICENOW_URL: ${{ secrets.SERVICENOW_URL}} - SERVICENOW_PASSWORD: ${{ secrets.SERVICENOW_PASSWORD}} - SERVICENOW_DEVELOPER_USERNAME: ${{ secrets.SERVICENOW_DEVELOPER_USERNAME}} - SERVICENOW_DEVELOPER_PASSWORD: ${{ secrets.SERVICENOW_DEVELOPER_PASSWORD}} - SNOWFLAKE_ACCOUNT_NAME: ${{ secrets.SNOWFLAKE_ACCOUNT_NAME}} - SNOWFLAKE_USERNAME: ${{ secrets.SNOWFLAKE_USERNAME}} - SNOWFLAKE_PASSWORD: ${{ secrets.SNOWFLAKE_PASSWORD}} - ZENDESK_URL: ${{ secrets.ZENDESK_URL}} - ZENDESK_USERNAME: ${{ secrets.ZENDESK_USERNAME}} - ZENDESK_PASSWORD: ${{ secrets.ZENDESK_PASSWORD}} - CONNECTOR_GITHUB_ACCESS_TOKEN: ${{ secrets.CONNECTOR_GITHUB_ACCESS_TOKEN}} - CI_GITHUB_TOKEN: ${{ secrets.CI_GITHUB_TOKEN}} - AUDIT_LOG_CLUSTER_BOOTSTRAP_SERVERS: ${{ secrets.AUDIT_LOG_CLUSTER_BOOTSTRAP_SERVERS}} - AUDIT_LOG_CLUSTER_API_KEY: ${{ secrets.AUDIT_LOG_CLUSTER_API_KEY}} - AUDIT_LOG_CLUSTER_API_SECRET: ${{ secrets.AUDIT_LOG_CLUSTER_API_SECRET}} - NGROK_AUTH_TOKEN: ${{ secrets.NGROK_CI_AUTH_TOKEN}} - DATABRICKS_AWS_BUCKET_NAME: ${{ secrets.DATABRICKS_AWS_BUCKET_NAME}} - DATABRICKS_AWS_BUCKET_REGION: ${{ secrets.DATABRICKS_AWS_BUCKET_REGION}} - DATABRICKS_AWS_STAGING_S3_ACCESS_KEY_ID: ${{ secrets.DATABRICKS_AWS_STAGING_S3_ACCESS_KEY_ID}} - DATABRICKS_AWS_STAGING_S3_SECRET_ACCESS_KEY: ${{ secrets.DATABRICKS_AWS_STAGING_S3_SECRET_ACCESS_KEY}} - DATABRICKS_SERVER_HOSTNAME: ${{ secrets.DATABRICKS_SERVER_HOSTNAME}} - DATABRICKS_HTTP_PATH: ${{ secrets.DATABRICKS_HTTP_PATH}} - DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN}} - ORACLE_CONTAINER_REGISTRY_USERNAME: ${{ secrets.ORACLE_CONTAINER_REGISTRY_USERNAME}} - ORACLE_CONTAINER_REGISTRY_PASSWORD: ${{ secrets.ORACLE_CONTAINER_REGISTRY_PASSWORD}} - GCP_KEYFILE_CONTENT: ${{ secrets.GCP_KEYFILE_CONTENT}} - GCP_PROJECT: ${{ secrets.GCP_PROJECT}} - HPE_MAPR_EMAIL: ${{ secrets.HPE_MAPR_EMAIL}} - HPE_MAPR_TOKEN: ${{ secrets.HPE_MAPR_TOKEN}} - - execute_one_test: - if: ${{ github.event.inputs.test_name != '' }} - runs-on: ubuntu-latest - name: ${{ matrix.environment }} ${{ matrix.test_list }} - strategy: - fail-fast: false - matrix: - tag: ["7.5.3"] - environment: ["ccloud", "sasl-ssl", "sasl-plain", "2way-ssl", "sasl-scram", "kraft-external-plaintext", "kraft-plaintext", "kerberos", "ssl_kerberos", "ldap-authorizer-sasl-plain", "ldap-sasl-plain"] - test_list : [ - "🚀 ${{ github.event.inputs.test_name }}" - ] - steps: - - # - name: Maximize build space - # uses: easimon/maximize-build-space@master - # with: - # root-reserve-mb: 512 - # swap-size-mb: 1024 - # remove-dotnet: 'true' - # remove-android: 'true' - # remove-haskell: 'true' - # remove-codeql: 'true' - - - name: Checkout code - uses: actions/checkout@v4 - with: - repository: vdesabou/kafka-docker-playground - fetch-depth: 0 - - - name: "Free up disk space" - run: | - df -h - sudo apt-get -qq purge build-essential ghc* - sudo apt-get clean - sudo apt-get install expect fzf coreutils -y - docker system prune -af - sudo rm -rf /usr/share/dotnet - sudo rm -rf /opt/ghc - sudo rm -rf "/usr/local/share/boost" - sudo rm -rf "$AGENT_TOOLSDIRECTORY" - - sudo docker rmi $(docker image ls -aq) >/dev/null 2>&1 || true - sudo rm -rf \ - /usr/share/dotnet /usr/local/lib/android /opt/ghc \ - /usr/local/share/powershell /usr/share/swift /usr/local/.ghcup \ - /usr/lib/jvm || true - echo "some directories deleted" - sudo apt install aptitude -y >/dev/null 2>&1 - sudo aptitude purge aria2 ansible azure-cli shellcheck rpm xorriso zsync \ - esl-erlang firefox gfortran-8 gfortran-9 google-chrome-stable \ - google-cloud-sdk imagemagick \ - libmagickcore-dev libmagickwand-dev libmagic-dev ant ant-optional kubectl \ - mercurial apt-transport-https mono-complete libmysqlclient \ - unixodbc-dev yarn chrpath libssl-dev libxft-dev \ - libfreetype6 libfreetype6-dev libfontconfig1 libfontconfig1-dev \ - snmp pollinate libpq-dev postgresql-client powershell ruby-full \ - sphinxsearch subversion mongodb-org azure-cli microsoft-edge-stable \ - -y -f >/dev/null 2>&1 - sudo aptitude purge google-cloud-sdk -f -y >/dev/null 2>&1 - sudo aptitude purge microsoft-edge-stable -f -y >/dev/null 2>&1 || true - sudo apt purge microsoft-edge-stable -f -y >/dev/null 2>&1 || true - sudo aptitude purge '~n ^mysql' -f -y >/dev/null 2>&1 - sudo aptitude purge '~n ^php' -f -y >/dev/null 2>&1 - sudo aptitude purge '~n ^dotnet' -f -y >/dev/null 2>&1 - sudo apt-get autoremove -y >/dev/null 2>&1 - sudo apt-get autoclean -y >/dev/null 2>&1 - echo "some packages purged" - - df -h - - - name: "Install confluent CLI" - run: | - curl -L --http1.1 https://cnfl.io/cli | sudo sh -s -- -b /usr/local/bin - export PATH=$PATH:/usr/local/bin - - - name: Decrypt secrets.tar - run: | - ./.github/scripts/decrypt_secret.sh - tar xvf secrets.tar - rm secrets.tar - mkdir -p $HOME/.aws - mv aws_credentials_with_assuming_iam_role $HOME/.aws/credentials-with-assuming-iam-role - mv aws_credentials_aws_account_with_assume_role $HOME/.aws/credentials_aws_account_with_assume_role - chmod -R a+rw $HOME/.aws - mkdir -p $HOME/.confluent - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - env: - SECRETS_ENCRYPTION_PASSWORD: ${{ secrets.SECRETS_ENCRYPTION_PASSWORD }} - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME}} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD}} - - - name: Build and Test - run: | - export PATH=$PATH:$GITHUB_WORKSPACE/scripts/cli - bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" "${{ matrix.environment }}" - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} - AWS_REGION: ${{ secrets.AWS_REGION}} - AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID}} - AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY}} - AWS_STS_ROLE_ARN: ${{ secrets.AWS_STS_ROLE_ARN}} - AZ_USER: ${{ secrets.AZ_USER}} - AZ_PASS: ${{ secrets.AZ_PASS}} - AZURE_SUBSCRIPTION_NAME: ${{ secrets.AZURE_SUBSCRIPTION_NAME}} - CONFLUENT_CLOUD_EMAIL: ${{ secrets.CONFLUENT_CLOUD_EMAIL}} - CONFLUENT_CLOUD_PASSWORD: ${{ secrets.CONFLUENT_CLOUD_PASSWORD}} - ENVIRONMENT: ${{ secrets.ENVIRONMENT}} - CLUSTER_NAME: ${{ secrets.CLUSTER_NAME}} - CLUSTER_REGION: ${{ secrets.CLUSTER_REGION}} - CLUSTER_CLOUD: ${{ secrets.CLUSTER_CLOUD}} - CLUSTER_CREDS: ${{ secrets.CLUSTER_CREDS}} - AWS_DATABRICKS_CLUSTER_NAME: ${{ secrets.AWS_DATABRICKS_CLUSTER_NAME}} - AWS_DATABRICKS_CLUSTER_REGION: ${{ secrets.AWS_DATABRICKS_CLUSTER_REGION}} - AWS_DATABRICKS_CLUSTER_CLOUD: ${{ secrets.AWS_DATABRICKS_CLUSTER_CLOUD}} - AWS_DATABRICKS_CLUSTER_CREDS: ${{ secrets.AWS_DATABRICKS_CLUSTER_CREDS}} - GCP_CLUSTER_NAME: ${{ secrets.GCP_CLUSTER_NAME}} - GCP_CLUSTER_REGION: ${{ secrets.GCP_CLUSTER_REGION}} - GCP_CLUSTER_CLOUD: ${{ secrets.GCP_CLUSTER_CLOUD}} - GCP_CLUSTER_CREDS: ${{ secrets.GCP_CLUSTER_CREDS}} - AZURE_CLUSTER_NAME: ${{ secrets.AZURE_CLUSTER_NAME}} - AZURE_CLUSTER_REGION: ${{ secrets.AZURE_CLUSTER_REGION}} - AZURE_CLUSTER_CLOUD: ${{ secrets.AZURE_CLUSTER_CLOUD}} - AZURE_CLUSTER_CREDS: ${{ secrets.AZURE_CLUSTER_CREDS}} - SCHEMA_REGISTRY_CREDS: ${{ secrets.SCHEMA_REGISTRY_CREDS}} - CONFLUENT_LICENSE: ${{ secrets.CONFLUENT_LICENSE}} - SALESFORCE_USERNAME: ${{ secrets.SALESFORCE_USERNAME}} - SALESFORCE_PASSWORD: ${{ secrets.SALESFORCE_PASSWORD}} - SALESFORCE_CONSUMER_KEY: ${{ secrets.SALESFORCE_CONSUMER_KEY}} - SALESFORCE_CONSUMER_PASSWORD: ${{ secrets.SALESFORCE_CONSUMER_PASSWORD}} - SALESFORCE_SECURITY_TOKEN: ${{ secrets.SALESFORCE_SECURITY_TOKEN}} - SALESFORCE_INSTANCE: ${{ secrets.SALESFORCE_INSTANCE}} - SALESFORCE_USERNAME_ACCOUNT2: ${{ secrets.SALESFORCE_USERNAME_ACCOUNT2}} - SALESFORCE_PASSWORD_ACCOUNT2: ${{ secrets.SALESFORCE_PASSWORD_ACCOUNT2}} - SALESFORCE_SECURITY_TOKEN_ACCOUNT2: ${{ secrets.SALESFORCE_SECURITY_TOKEN_ACCOUNT2}} - SALESFORCE_CONSUMER_KEY_ACCOUNT2: ${{ secrets.SALESFORCE_CONSUMER_KEY_ACCOUNT2}} - SALESFORCE_CONSUMER_PASSWORD_ACCOUNT2: ${{ secrets.SALESFORCE_CONSUMER_PASSWORD_ACCOUNT2}} - SALESFORCE_CONSUMER_KEY_WITH_JWT: ${{ secrets.SALESFORCE_CONSUMER_KEY_WITH_JWT}} - SALESFORCE_CONSUMER_PASSWORD_WITH_JWT: ${{ secrets.SALESFORCE_CONSUMER_PASSWORD_WITH_JWT}} - DD_API_KEY: ${{ secrets.DD_API_KEY}} - DD_APP_KEY: ${{ secrets.DD_APP_KEY}} - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME}} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD}} - JIRA_URL: ${{ secrets.JIRA_URL}} - JIRA_USERNAME: ${{ secrets.JIRA_USERNAME}} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN}} - MARKETO_ENDPOINT_URL: ${{ secrets.MARKETO_ENDPOINT_URL}} - MARKETO_CLIENT_ID: ${{ secrets.MARKETO_CLIENT_ID}} - MARKETO_CLIENT_SECRET: ${{ secrets.MARKETO_CLIENT_SECRET}} - PAGERDUTY_USER_EMAIL: ${{ secrets.PAGERDUTY_USER_EMAIL}} - PAGERDUTY_API_KEY: ${{ secrets.PAGERDUTY_API_KEY}} - PAGERDUTY_SERVICE_ID: ${{ secrets.PAGERDUTY_SERVICE_ID}} - CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_KEY: ${{ secrets.CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_KEY}} - CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_SECRET: ${{ secrets.CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_SECRET}} - SERVICENOW_URL: ${{ secrets.SERVICENOW_URL}} - SERVICENOW_PASSWORD: ${{ secrets.SERVICENOW_PASSWORD}} - SERVICENOW_DEVELOPER_USERNAME: ${{ secrets.SERVICENOW_DEVELOPER_USERNAME}} - SERVICENOW_DEVELOPER_PASSWORD: ${{ secrets.SERVICENOW_DEVELOPER_PASSWORD}} - SNOWFLAKE_ACCOUNT_NAME: ${{ secrets.SNOWFLAKE_ACCOUNT_NAME}} - SNOWFLAKE_USERNAME: ${{ secrets.SNOWFLAKE_USERNAME}} - SNOWFLAKE_PASSWORD: ${{ secrets.SNOWFLAKE_PASSWORD}} - ZENDESK_URL: ${{ secrets.ZENDESK_URL}} - ZENDESK_USERNAME: ${{ secrets.ZENDESK_USERNAME}} - ZENDESK_PASSWORD: ${{ secrets.ZENDESK_PASSWORD}} - CONNECTOR_GITHUB_ACCESS_TOKEN: ${{ secrets.CONNECTOR_GITHUB_ACCESS_TOKEN}} - CI_GITHUB_TOKEN: ${{ secrets.CI_GITHUB_TOKEN}} - AUDIT_LOG_CLUSTER_BOOTSTRAP_SERVERS: ${{ secrets.AUDIT_LOG_CLUSTER_BOOTSTRAP_SERVERS}} - AUDIT_LOG_CLUSTER_API_KEY: ${{ secrets.AUDIT_LOG_CLUSTER_API_KEY}} - AUDIT_LOG_CLUSTER_API_SECRET: ${{ secrets.AUDIT_LOG_CLUSTER_API_SECRET}} - NGROK_AUTH_TOKEN: ${{ secrets.NGROK_CI_AUTH_TOKEN}} - DATABRICKS_AWS_BUCKET_NAME: ${{ secrets.DATABRICKS_AWS_BUCKET_NAME}} - DATABRICKS_AWS_BUCKET_REGION: ${{ secrets.DATABRICKS_AWS_BUCKET_REGION}} - DATABRICKS_AWS_STAGING_S3_ACCESS_KEY_ID: ${{ secrets.DATABRICKS_AWS_STAGING_S3_ACCESS_KEY_ID}} - DATABRICKS_AWS_STAGING_S3_SECRET_ACCESS_KEY: ${{ secrets.DATABRICKS_AWS_STAGING_S3_SECRET_ACCESS_KEY}} - DATABRICKS_SERVER_HOSTNAME: ${{ secrets.DATABRICKS_SERVER_HOSTNAME}} - DATABRICKS_HTTP_PATH: ${{ secrets.DATABRICKS_HTTP_PATH}} - DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN}} - ORACLE_CONTAINER_REGISTRY_USERNAME: ${{ secrets.ORACLE_CONTAINER_REGISTRY_USERNAME}} - ORACLE_CONTAINER_REGISTRY_PASSWORD: ${{ secrets.ORACLE_CONTAINER_REGISTRY_PASSWORD}} - GCP_KEYFILE_CONTENT: ${{ secrets.GCP_KEYFILE_CONTENT}} - GCP_PROJECT: ${{ secrets.GCP_PROJECT}} - HPE_MAPR_EMAIL: ${{ secrets.HPE_MAPR_EMAIL}} - HPE_MAPR_TOKEN: ${{ secrets.HPE_MAPR_TOKEN}} diff --git a/.github/workflows/ci-self-managed.yml b/.github/workflows/ci-self-managed.yml index 0915c6ac87..77c8e9547f 100644 --- a/.github/workflows/ci-self-managed.yml +++ b/.github/workflows/ci-self-managed.yml @@ -91,6 +91,7 @@ jobs: env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} + S3_PROVIDER_INTEGRATION_ID: ${{ secrets.S3_PROVIDER_INTEGRATION_ID}} AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID}} AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY}} AWS_STS_ROLE_ARN: ${{ secrets.AWS_STS_ROLE_ARN}} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 602b69355b..6f32a4af8d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -229,6 +229,7 @@ jobs: env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} + S3_PROVIDER_INTEGRATION_ID: ${{ secrets.S3_PROVIDER_INTEGRATION_ID}} AWS_REGION: ${{ secrets.AWS_REGION}} AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID}} AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY}} @@ -419,6 +420,7 @@ jobs: env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} + S3_PROVIDER_INTEGRATION_ID: ${{ secrets.S3_PROVIDER_INTEGRATION_ID}} AWS_REGION: ${{ secrets.AWS_REGION}} AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID}} AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY}} From d64c2cdb376694bc3419124779e7cac7328b8567 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 13 Jan 2025 09:14:55 +0100 Subject: [PATCH 144/659] wip --- .../connect-marketo-source/marketo-source.sh | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/connect/connect-marketo-source/marketo-source.sh b/connect/connect-marketo-source/marketo-source.sh index ac25003db5..9473e07260 100755 --- a/connect/connect-marketo-source/marketo-source.sh +++ b/connect/connect-marketo-source/marketo-source.sh @@ -47,24 +47,27 @@ ACCESS_TOKEN=$(docker exec connect \ curl -s -X GET \ "${MARKETO_ENDPOINT_URL}/identity/oauth/token?grant_type=client_credentials&client_id=$MARKETO_CLIENT_ID&client_secret=$MARKETO_CLIENT_SECRET" | jq -r .access_token) -log "Create one lead to Marketo" -LEAD_FIRSTNAME=John_$RANDOM -LEAD_LASTNAME=Doe_$RANDOM -docker exec connect \ - curl -s -X POST \ - "${MARKETO_ENDPOINT_URL}/rest/v1/leads.json?access_token=$ACCESS_TOKEN" \ - -H 'Accept: application/json' \ - -H 'Content-Type: application/json' \ - -H 'cache-control: no-cache' \ - -d "{ \"action\":\"createOrUpdate\", \"lookupField\":\"email\", \"input\":[ { \"lastName\":\"$LEAD_LASTNAME\", \"firstName\":\"$LEAD_FIRSTNAME\", \"middleName\":null, \"email\":\"$LEAD_FIRSTNAME.$LEAD_LASTNAME@email.com\" } ]}" - -# since last hour +log "Create 3 leads to Marketo" +for((i=0;i<3;i++)) +do + LEAD_FIRSTNAME="John_$RANDOM_${i}" + LEAD_LASTNAME="Doe_$RANDOM_${i}" + + log "Lead: $LEAD_FIRSTNAME $LEAD_LASTNAME" + docker exec connect \ + curl -s -X POST \ + "${MARKETO_ENDPOINT_URL}/rest/v1/leads.json?access_token=$ACCESS_TOKEN" \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'cache-control: no-cache' \ + -d "{ \"action\":\"createOrUpdate\", \"lookupField\":\"email\", \"input\":[ { \"lastName\":\"$LEAD_LASTNAME\", \"firstName\":\"$LEAD_FIRSTNAME\", \"middleName\":null, \"email\":\"$LEAD_FIRSTNAME.$LEAD_LASTNAME@email.com\" } ]}" +done if [[ "$OSTYPE" == "darwin"* ]] then - SINCE=$(date -v-3H +%Y-%m-%dT%H:%M:%SZ) + SINCE=$(date -v-8H +%Y-%m-%dT%H:%M:%SZ) else - SINCE=$(date -d '3 hour ago' +%Y-%m-%dT%H:%M:%SZ) + SINCE=$(date -d '8 hour ago' +%Y-%m-%dT%H:%M:%SZ) fi # playground debug log-level set --package "org.apache.http" --level TRACE From 787458d08728bc36e5f822f49e4842c6edad0e46 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 13 Jan 2025 09:15:03 +0100 Subject: [PATCH 145/659] wip --- scripts/cli/confluent-hub-plugin-list.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index 4f0755aa3a..f107cac00c 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -1,3 +1,4 @@ +Onibex/snowflake-sink-connector a2solutions/oracdc-kafka ably/kafka-connect-ably adobeinc/streaming-connect-sink From 76d1faf2bef35e286e95dd5d293becc7e99eeab8 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 13 Jan 2025 11:16:09 +0100 Subject: [PATCH 146/659] Update release-notes.yml --- .github/release-notes.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/release-notes.yml b/.github/release-notes.yml index 289cd0deba..68855386a1 100644 --- a/.github/release-notes.yml +++ b/.github/release-notes.yml @@ -3,4 +3,4 @@ changelog: - title: "🌟 Enhancements" labels: ["enhancement"] - title: "🐛 Bugs" - labels: ["fix"] + labels: ["fix required"] From 2f5c8f8a6558333810c7f24a3f3182bbab818a67 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 13 Jan 2025 11:20:53 +0100 Subject: [PATCH 147/659] Update release-notes.yml --- .github/release-notes.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/release-notes.yml b/.github/release-notes.yml index 68855386a1..724509efdd 100644 --- a/.github/release-notes.yml +++ b/.github/release-notes.yml @@ -3,4 +3,4 @@ changelog: - title: "🌟 Enhancements" labels: ["enhancement"] - title: "🐛 Bugs" - labels: ["fix required"] + labels: ["bug"] From f7e306ecabcb2115099dd6584f382598202a10fe Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 13 Jan 2025 11:47:50 +0100 Subject: [PATCH 148/659] #6005 --- scripts/cli/playground | 6 ++++-- scripts/cli/src/commands/connector/create-or-update.sh | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index a14a485360..e4c8b49963 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -24836,12 +24836,14 @@ else log "🪵 creating $connector_type connector $connector with --initial-state: $initial_state" # add mandatory name field - new_json_content=$(echo "$json_content" | jq -c ". + {\"name\": \"$connector\"}") + new_json_content=$(echo "$json_content" | sed 's/&/:AMPERSAND:/g' | jq -c ". + {\"name\": \"$connector\"}") sed -e "s|:CONNECTOR_NAME:|$connector|g" \ -e "s|:CONNECTOR_CONFIG:|$new_json_content|g" \ -e "s|:CONNECTOR_INITIAL_STATE:|$initial_state|g" \ - $root_folder/scripts/cli/src/create-connector-post-template-initial-state.json > ${connector_with_initial_state_file} + $root_folder/scripts/cli/src/create-connector-post-template-initial-state.json > /tmp/connector_with_initial_state_file.json + + sed -e "s|:AMPERSAND:|\&|g" /tmp/connector_with_initial_state_file.json > ${connector_with_initial_state_file} handle_onprem_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" --data @$connector_with_initial_state_file $connect_url/connectors" else diff --git a/scripts/cli/src/commands/connector/create-or-update.sh b/scripts/cli/src/commands/connector/create-or-update.sh index 3eb9475cae..d0b25f6c8f 100644 --- a/scripts/cli/src/commands/connector/create-or-update.sh +++ b/scripts/cli/src/commands/connector/create-or-update.sh @@ -275,12 +275,14 @@ else then log "🪵 creating $connector_type connector $connector with --initial-state: $initial_state" # add mandatory name field - new_json_content=$(echo "$json_content" | jq -c ". + {\"name\": \"$connector\"}") + new_json_content=$(echo "$json_content" | sed 's/&/:AMPERSAND:/g' | jq -c ". + {\"name\": \"$connector\"}") sed -e "s|:CONNECTOR_NAME:|$connector|g" \ -e "s|:CONNECTOR_CONFIG:|$new_json_content|g" \ -e "s|:CONNECTOR_INITIAL_STATE:|$initial_state|g" \ - $root_folder/scripts/cli/src/create-connector-post-template-initial-state.json > ${connector_with_initial_state_file} + $root_folder/scripts/cli/src/create-connector-post-template-initial-state.json > /tmp/connector_with_initial_state_file.json + + sed -e "s|:AMPERSAND:|\&|g" /tmp/connector_with_initial_state_file.json > ${connector_with_initial_state_file} handle_onprem_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" --data @$connector_with_initial_state_file $connect_url/connectors" else From 85f99ac744975c67d8db71fc874cd5eb95b226eb Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 13 Jan 2025 12:04:36 +0100 Subject: [PATCH 149/659] Update update-changelogs.yml --- .github/workflows/update-changelogs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-changelogs.yml b/.github/workflows/update-changelogs.yml index 8e4abdd35f..823b537514 100644 --- a/.github/workflows/update-changelogs.yml +++ b/.github/workflows/update-changelogs.yml @@ -54,7 +54,7 @@ jobs: echo "" >> ./docs/changelog.md current_month=$(date +"%B %Y") echo "## ${current_month}" >> ./docs/changelog.md - echo "${{ steps.read_release_file.outputs.content }}" | sed 's/^#/##/g' | sed 's/###/####/g' >> ./docs/changelog.md + echo "${{ steps.read_release_file.outputs.content }}" | sed 's/^#/##/g' | sed 's/###/#####/g' >> ./docs/changelog.md cat changelog_tmp.md >> ./docs/changelog.md - name: Pushes docs From 28a84156a132f57132a7994de01445adb302e8dc Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 13 Jan 2025 14:19:52 +0100 Subject: [PATCH 150/659] skip repro model folder --- scripts/cli/playground | 14 +++++++++++--- scripts/cli/src/commands/get-ci-result.sh | 14 +++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index e4c8b49963..2277507a54 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -13436,6 +13436,11 @@ playground_get_ci_result_command() { log "🐛📂 not deleting tmp dir $tmp_dir" fi + if [[ "$dir2" == reproduction-models* ]] + then + exit 0 + fi + content_file="$tmp_dir/content.md" curl -s -o $content_file https://raw.githubusercontent.com/vdesabou/kafka-docker-playground-docs/main/docs/content.md @@ -13444,15 +13449,18 @@ playground_get_ci_result_command() { result_not_tested="$(grep "$dir2" $content_file | sed -n 's/.*\[not tested\].*/🤖CI status: 🤷‍♂️ not tested/p')" # print only result not empty - if [ -n "$result_ok" ]; then + if [ -n "$result_ok" ] + then log "$result_ok" fi - if [ -n "$result_fail" ]; then + if [ -n "$result_fail" ] + then logwarn "$result_fail" fi - if [ -n "$result_not_tested" ]; then + if [ -n "$result_not_tested" ] + then log "$result_not_tested" fi } diff --git a/scripts/cli/src/commands/get-ci-result.sh b/scripts/cli/src/commands/get-ci-result.sh index 216517c5a0..5566ab6842 100644 --- a/scripts/cli/src/commands/get-ci-result.sh +++ b/scripts/cli/src/commands/get-ci-result.sh @@ -19,6 +19,11 @@ else log "🐛📂 not deleting tmp dir $tmp_dir" fi +if [[ "$dir2" == reproduction-models* ]] +then + exit 0 +fi + content_file="$tmp_dir/content.md" curl -s -o $content_file https://raw.githubusercontent.com/vdesabou/kafka-docker-playground-docs/main/docs/content.md @@ -27,14 +32,17 @@ result_fail="$(grep "$dir2" $content_file | sed -n 's/.*\[CI \(fail\)\].*(\(http result_not_tested="$(grep "$dir2" $content_file | sed -n 's/.*\[not tested\].*/🤖CI status: 🤷‍♂️ not tested/p')" # print only result not empty -if [ -n "$result_ok" ]; then +if [ -n "$result_ok" ] +then log "$result_ok" fi -if [ -n "$result_fail" ]; then +if [ -n "$result_fail" ] +then logwarn "$result_fail" fi -if [ -n "$result_not_tested" ]; then +if [ -n "$result_not_tested" ] +then log "$result_not_tested" fi \ No newline at end of file From c3bed0120b3cffc78074c6d3e6ad2b40a49a538f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 13 Jan 2025 14:20:34 +0100 Subject: [PATCH 151/659] check_if_continue --- scripts/cli/playground | 1 + scripts/cli/src/commands/get-ci-result.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/scripts/cli/playground b/scripts/cli/playground index 2277507a54..126913555b 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -13457,6 +13457,7 @@ playground_get_ci_result_command() { if [ -n "$result_fail" ] then logwarn "$result_fail" + check_if_continue fi if [ -n "$result_not_tested" ] diff --git a/scripts/cli/src/commands/get-ci-result.sh b/scripts/cli/src/commands/get-ci-result.sh index 5566ab6842..cb0e5eb371 100644 --- a/scripts/cli/src/commands/get-ci-result.sh +++ b/scripts/cli/src/commands/get-ci-result.sh @@ -40,6 +40,7 @@ fi if [ -n "$result_fail" ] then logwarn "$result_fail" + check_if_continue fi if [ -n "$result_not_tested" ] From 972de74d1e1cb3cfcbdc464e2939eb9d6b03cf87 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 13 Jan 2025 16:50:23 +0100 Subject: [PATCH 152/659] get ci results --- scripts/cli/completions.bash | 802 ++++++++++++++++++----------------- scripts/cli/playground | 1 + scripts/cli/playground.json | 7 + scripts/cli/playground.yaml | 6 + scripts/cli/src/bashly.yml | 1 - 5 files changed, 417 insertions(+), 400 deletions(-) diff --git a/scripts/cli/completions.bash b/scripts/cli/completions.bash index 309a6e2965..2b0dbcf515 100644 --- a/scripts/cli/completions.bash +++ b/scripts/cli/completions.bash @@ -72,14 +72,14 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; - *'connector offsets get-offsets-request-status'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") - ;; - *'connector open-ccloud-connector-in-browser'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; + *'connector offsets get-offsets-request-status'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + ;; + *'tcp-proxy toggle-reads-client'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; @@ -156,10 +156,6 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'ec2 sync-repro-folder ec2-to-local'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") - ;; - *'config container-kill-all-before-run'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -168,8 +164,8 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'container set-environment-variables'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --env --help --restore-original-values -c -h")" -- "$cur") + *'ec2 sync-repro-folder ec2-to-local'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; *'tcp-proxy toggle-accept-connections'*) @@ -180,6 +176,10 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'container set-environment-variables'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --env --help --restore-original-values -c -h")" -- "$cur") + ;; + *'connector offsets reset'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -192,6 +192,10 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; + *'ec2 sync-repro-folder ec2-to-local'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + ;; + *'connector select-config'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -200,10 +204,6 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'ec2 sync-repro-folder ec2-to-local'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") - ;; - *'cleanup-cloud-resources'*'--resource') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure ccloud salesforce")" -- "$cur") ;; @@ -220,27 +220,27 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'connector offsets get'*'--connector') + *'debug flight-recorder'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + + *'connector show-config'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'topic produce'*'--compression-codec') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "gzip snappy lz4 zstd")" -- "$cur") + *'connector show-config-parameters'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-refresh --help --only-show-json --open --verbose -c -h -o -v")" -- "$cur") ;; - *'debug flight-recorder'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic produce'*'--compression-codec') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "gzip snappy lz4 zstd")" -- "$cur") ;; *'topic set-schema-compatibility'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector show-config-parameters'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-refresh --help --only-show-json --open --verbose -c -h -o -v")" -- "$cur") - ;; - - *'connector show-config'*'--connector') + *'connector offsets get'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -248,108 +248,108 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'container change-jdk'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'tcp-proxy toggle-writes-service'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; *'debug enable-remote-debugging'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy toggle-writes-service'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'container change-jdk'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy break'*'--connection-id') + *'tcp-proxy delay'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'tcp-proxy toggle-reads-service'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'topic produce'*'--validate-config') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") ;; - *'tcp-proxy toggle-writes-client'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'debug block-traffic'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy delay'*'--connection-id') + *'tcp-proxy break'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'tools install-vscode-extension'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'connector log-level'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'topic produce'*'--validate-config') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") - ;; - - *'debug block-traffic'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - *'topic set-schema-compatibility'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --topic --verbose -h -t -v")" -- "$cur") ;; + *'tcp-proxy toggle-reads-service'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + ;; + *'topic display-consumer-offsets'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --verbose -h -v")" -- "$cur") ;; - *'tools read-parquet-file'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") + *'tcp-proxy toggle-writes-client'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'debug enable-remote-debugging'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'tools install-vscode-extension'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'connector-plugin search-jar'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; + *'update-version'*'--connector-zip') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") + ;; + *'tcp-proxy toggle-reads-client'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'debug flight-recorder'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") + *'tools read-parquet-file'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") + ;; + + *'update-version'*'--connector-jar') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") + ;; + + *'debug enable-remote-debugging'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; *'container change-jdk'*'--version') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "8 11 17 21 22")" -- "$cur") ;; - *'connector show-lag'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug flight-recorder'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") ;; *'connector snippets'*'--converter') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "avro protobuf json-schema json json-schema-enabled string bytearray")" -- "$cur") ;; - *'update-version'*'--connector-zip') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") - ;; - - *'update-version'*'--connector-jar') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") + *'connector show-lag'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'connector restart'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug generate-diagnostics'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector create-or-update'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container unpause'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector create-or-update'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; *'debug thread-dump'*'--container') @@ -360,32 +360,24 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic consume'*'--value-subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") - ;; - - *'connector create-or-update'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug generate-diagnostics'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'connector unpause'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector create-or-update'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") - ;; - *'topic produce'*'--compatibility') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; - *'connector resume'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container unpause'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector-plugin search-jar'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--class --connector-plugin --connector-tag --help -c -h")" -- "$cur") + *'topic consume'*'--value-subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; *'connector update'*'--connector') @@ -396,10 +388,26 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; + *'connector delete'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'connector resume'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + *'connector-plugin versions'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; + *'connector-plugin search-jar'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--class --connector-plugin --connector-tag --help -c -h")" -- "$cur") + ;; + + *'container resume'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + *'debug block-traffic'*'--action') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") ;; @@ -412,31 +420,27 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "true false")" -- "$cur") ;; - *'container resume'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic get-number-records'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector delete'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container get-ip-addresses'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'debug heap-dump'*'--container') + *'container get-properties'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic get-number-records'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'get-jmx-metrics'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'debug log-level set'*'--level') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'topic consume'*'--key-subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") - ;; - - *'get-jmx-metrics'*'--container') + *'debug heap-dump'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -444,24 +448,20 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'connector pause'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'container get-properties'*'-c') + *'container pause'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container get-ip-addresses'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'topic consume'*'--key-subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'container pause'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector log-level'*'--level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'tcp-proxy close-connection'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'connector pause'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'tools read-avro-file'*'--file') @@ -472,91 +472,107 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --initial-state --level --offsets --package --skip-automatic-connector-config --validate --verbose --wait-for-zero-lag -c -h -l -p -v")" -- "$cur") ;; - *'connector log-level'*'--level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'tcp-proxy close-connection'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'connector offsets reset'*'-c') + *'connector offsets alter'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tcp-proxy start'*'--hostname') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector offsets reset'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'container logs'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy get-connections'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'repro bootstrap'*'--pipeline') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro --sink-only "$cur")")" -- "$cur") ;; - *'connector select-config'*'-c') + *'connector stop'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'repro bootstrap'*'--producer') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") - ;; - - *'connector offsets alter'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'tcp-proxy start'*'--hostname') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'debug block-traffic'*'--port') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'debug tcp-dump'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'repro bootstrap'*'--producer') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") ;; - *'tools read-parquet-file'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") + *'tcp-proxy get-connections'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'ec2 create'*'--instance-type') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "c1.medium c1.xlarge c3.2xlarge c3.4xlarge c3.8xlarge c3.large c3.xlarge c4.2xlarge c4.4xlarge c4.large c4.xlarge m1.large m1.medium m1.small m1.xlarge m2.2xlarge m2.4xlarge m2.xlarge m3.2xlarge m3.large m3.medium m3.xlarge m4.10xlarge m4.2xlarge m4.4xlarge m4.large m4.xlarge t1.micro t2.large t2.medium t2.micro t2.nano t2.small t3.2xlarge")" -- "$cur") + *'debug tcp-dump'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'config check-repo-version'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; + *'tools read-parquet-file'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") + ;; + *'container exec'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'container kill'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + + *'ec2 create'*'--instance-type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "c1.medium c1.xlarge c3.2xlarge c3.4xlarge c3.8xlarge c3.large c3.xlarge c4.2xlarge c4.4xlarge c4.large c4.xlarge m1.large m1.medium m1.small m1.xlarge m2.2xlarge m2.4xlarge m2.xlarge m3.2xlarge m3.large m3.medium m3.xlarge m4.10xlarge m4.2xlarge m4.4xlarge m4.large m4.xlarge t1.micro t2.large t2.medium t2.micro t2.nano t2.small t3.2xlarge")" -- "$cur") + ;; + *'connector-plugin versions'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-plugin --force-refresh --help --last -c -h")" -- "$cur") ;; - *'connector stop'*'--connector') + *'connector select-config'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'repro bootstrap'*'--pipeline') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro --sink-only "$cur")")" -- "$cur") + *'schema set-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --subject --verbose -h -v")" -- "$cur") ;; - *'container kill'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'schema get-mode'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'topic produce'*'--reference') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + *'schema set-mode'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; *'container get-properties'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; + *'schema get-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") + ;; + *'schema register'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'config folder_zip_or_jar'*) + *'debug java-debug'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "enable disable")" -- "$cur") + ;; + + *'remove-all-docker-images'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -568,39 +584,15 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-environment-list "$cur")")" -- "$cur") ;; - *'topic get-number-records'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") - ;; - - *'remove-all-docker-images'*) + *'config folder_zip_or_jar'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'debug java-debug'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "enable disable")" -- "$cur") - ;; - - *'schema set-mode'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") - ;; - - *'schema get-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") - ;; - - *'schema get-mode'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") - ;; - - *'schema set-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --subject --verbose -h -v")" -- "$cur") - ;; - - *'debug flight-recorder'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic get-number-records'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") ;; - *'schema register'*'--schema') + *'topic produce'*'--reference') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; @@ -608,16 +600,16 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") ;; - *'connector offsets get'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'schema register'*'--schema') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; *'cleanup-cloud-resources'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--force --help --resource -h")" -- "$cur") ;; - *'connector offsets reset'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'connector show-config'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'tools read-parquet-file'*) @@ -628,16 +620,16 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'connector show-config'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug flight-recorder'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container change-jdk'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector offsets get'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'schema delete'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'connector offsets reset'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; *'tools read-avro-file'*'-f') @@ -648,70 +640,82 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ssl_all ssl_handshake class_loading kerberos")" -- "$cur") ;; - *'tcp-proxy start'*'--port') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") + *'schema delete'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'connector log-level'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'container change-jdk'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'schema set-mode'*'--mode') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") + *'connector offsets get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'connector log-level'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'cleanup-cloud-details'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'container exec'*'--shell') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'connector offsets get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'connector log-level'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; *'ec2 sync-repro-folder'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h ec2-to-local local-to-ec2")" -- "$cur") ;; + *'connector show-config'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-rest-endpoint --help --verbose -c -h -v")" -- "$cur") + ;; + + *'repro bootstrap'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") + ;; + + *'tcp-proxy start'*'--port') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") + ;; + *'debug block-traffic'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'topic describe'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + ;; + *'debug flight-recorder'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help -c -h")" -- "$cur") ;; - *'repro bootstrap'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") + *'connector log-level'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'cleanup-cloud-details'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'schema set-mode'*'--mode') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") ;; *'debug log-level set'*'-l') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'topic describe'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'connector show-lag'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector show-config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-rest-endpoint --help --verbose -c -h -v")" -- "$cur") + *'topic produce'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'ec2 delete'*'--instance') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") ;; - *'topic produce'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") - ;; - *'topic produce'*'--value') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; @@ -720,48 +724,44 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector show-lag'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - *'schema set-normalize'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --value --verbose -h -v")" -- "$cur") ;; - *'tools read-avro-file'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") - ;; - - *'debug tcp-dump'*'--port') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") - ;; - *'container ssh'*'--shell') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; + *'tools read-avro-file'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + ;; + *'container change-jdk'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --version -c -h")" -- "$cur") ;; - *'connector open-docs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") + *'debug tcp-dump'*'--port') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'debug log-level set'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --level --package -h -l -p")" -- "$cur") + *'run'*'--cluster-region') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-kafka-region-list "$cur")")" -- "$cur") ;; *'connector log-level'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level -c -h -l")" -- "$cur") ;; + *'debug log-level set'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --level --package -h -l -p")" -- "$cur") + ;; + *'debug log-level get'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --package -h -p")" -- "$cur") ;; - *'run'*'--cluster-region') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-kafka-region-list "$cur")")" -- "$cur") + *'connector open-docs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") ;; *'update-version'*'--tag') @@ -780,6 +780,14 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; + *'debug thread-dump'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + + *'connector restart'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + *'schema get'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; @@ -788,22 +796,30 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'connector restart'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container unpause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'container restart'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container unpause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic alter'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'debug thread-dump'*'-c') + *'container resume'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'connector resume'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'connector delete'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + *'connector show-lag'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --interval --max-wait --verbose -c -h -v")" -- "$cur") ;; @@ -812,44 +828,48 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") ;; - *'connector status'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'tools certs-create'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --output-folder --verbose -h -v")" -- "$cur") ;; - *'get-docker-compose'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'ec2 stop'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'debug java-debug'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector status'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector delete'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug java-debug'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'connector snippets'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--converter --dlq --help -h")" -- "$cur") ;; - *'tools certs-create'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --output-folder --verbose -h -v")" -- "$cur") + *'topic produce'*'--key') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'topic alter'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'ec2 open'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'topic produce'*'--key') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + *'connector update'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector versions'*) + *'get-docker-compose'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector resume'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'run'*'--connector-zip') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") + ;; + + *'connector versions'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'container recreate'*) @@ -860,43 +880,39 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'container resume'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'run'*'--connector-jar') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") ;; *'run'*'--cluster-cloud') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure")" -- "$cur") ;; - *'connector update'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'ec2 open'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'connector unpause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'ec2 stop'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'connector plugins'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help --verbose -h -v")" -- "$cur") ;; - *'run'*'--connector-jar') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") + *'debug thread-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'run'*'--connector-zip') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") + *'connector pause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'run'*'--cluster-name') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") + *'repro bootstrap'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") ;; - *'debug thread-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'container pause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector unpause'*) + *'connector restart'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; @@ -908,31 +924,15 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter get get-offsets-request-status reset")" -- "$cur") ;; - *'container restart'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") - ;; - *'container unpause'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'connector restart'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") - ;; - - *'connector pause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'connector plugins'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help --verbose -h -v")" -- "$cur") - ;; - - *'container pause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'container restart'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'get-jmx-metrics'*'-c') + *'debug heap-dump'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -940,48 +940,40 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "basic standard dedicated")" -- "$cur") ;; - *'repro bootstrap'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") - ;; - - *'debug heap-dump'*'-c') + *'get-jmx-metrics'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'config clipboard'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'run'*'--cluster-name') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") ;; - *'container resume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'run'*'--environment') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") ;; - *'debug java-debug'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help --type -c -h")" -- "$cur") + *'container logs'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'topic describe'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'debug tcp-dump'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'container logs'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector update'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") ;; - *'connector stop'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container resume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'connector resume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'config clipboard'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector update'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") + *'connector stop'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'container kill'*'-c') @@ -992,92 +984,96 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'debug java-debug'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help --type -c -h")" -- "$cur") + ;; + *'connector status'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'connector delete'*) + *'connector resume'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'run'*'--environment') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") + *'debug tcp-dump'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector-plugin'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h search-jar versions")" -- "$cur") + *'connector delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'repro bootstrap'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--custom-smt --description --file --help --pipeline -d -f -h")" -- "$cur") + *'connector-plugin'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h search-jar versions")" -- "$cur") ;; *'connector pause'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'topic consume'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'repro bootstrap'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--custom-smt --description --file --help --pipeline -d -f -h")" -- "$cur") ;; - *'debug heap-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") + *'schema register'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --metadata-property --schema --subject --verbose -h -v")" -- "$cur") ;; - *'container pause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'schema get-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; *'container ssh'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container ssh'*'-s') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") - ;; - - *'tcp-proxy break'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") + *'schema set-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") ;; - *'tcp-proxy delay'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") + *'container pause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'get-jmx-metrics'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --domain --help --open -c -d -h -o")" -- "$cur") + *'debug log-level'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h get set")" -- "$cur") ;; *'tcp-proxy start'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --delay-service-response --help --hostname --port --service-response-corrupt --skip-automatic-connector-config --throttle-service-response -h")" -- "$cur") ;; + *'tcp-proxy delay'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") + ;; + *'topic produce'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'debug log-level'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h get set")" -- "$cur") + *'tcp-proxy break'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") ;; - *'schema set-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") + *'get-jmx-metrics'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --domain --help --open -c -d -h -o")" -- "$cur") ;; - *'schema get-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") + *'container ssh'*'-s') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'schema register'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --metadata-property --schema --subject --verbose -h -v")" -- "$cur") + *'topic consume'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'container kill'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'debug heap-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") ;; - *'connector logs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") + *'repro import'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") ;; *'update-version'*) @@ -1088,16 +1084,12 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --duration --help --port -c -h")" -- "$cur") ;; - *'repro import'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") - ;; - - *'container logs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") + *'container kill'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'topic describe'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") + *'container exec'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--command --container --help --root --shell -c -h")" -- "$cur") ;; *'topic delete'*'-t') @@ -1108,36 +1100,36 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'container exec'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--command --container --help --root --shell -c -h")" -- "$cur") + *'connector logs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") ;; - *'container ssh'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") + *'container logs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") ;; - *'topic consume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--grep --help --key-subject --max-characters --max-messages --min-expected-messages --plot-latencies-timestamp-field --tail --timeout --topic --value-subject --verbose -h -t -v")" -- "$cur") + *'topic describe'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") ;; - *'topic alter'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'topic produce'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --max-nb-messages-to-generate --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") ;; - *'debug testssl'*) + *'switch-ccloud'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'config editor'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'container ssh'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") ;; - *'switch-ccloud'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'topic consume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--grep --help --key-subject --max-characters --max-messages --min-expected-messages --plot-latencies-timestamp-field --tail --timeout --topic --value-subject --verbose -h -t -v")" -- "$cur") ;; - *'topic produce'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --max-nb-messages-to-generate --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") + *'config editor'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'--output-level') @@ -1148,78 +1140,94 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --permanent --subject --verbose --version -h -v")" -- "$cur") ;; - *'ec2 delete'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") + *'get-ci-result'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'repro export'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help -h")" -- "$cur") + *'debug testssl'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'repro import'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + *'topic alter'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + ;; + + *'topic delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --skip-delete-schema --topic --verbose -h -t -v")" -- "$cur") ;; *'topic create'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --nb-partitions --topic --verbose -h -t -v")" -- "$cur") ;; - *'topic delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --skip-delete-schema --topic --verbose -h -t -v")" -- "$cur") + *'repro import'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'switch-back'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'repro export'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help -h")" -- "$cur") ;; - *'ec2 start'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'ec2 delete'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") + ;; + + *'switch-back'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'topic alter'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") ;; - *'schema get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") + *'ec2 start'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + ;; + + *'ec2 open'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; *'ec2 delete'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'ec2 create'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance-type --size --suffix -h")" -- "$cur") + *'topic list'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'ec2 open'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'ec2 create'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance-type --size --suffix -h")" -- "$cur") ;; - *'topic list'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'open'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") ;; *'ec2 stop'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'open'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") + *'schema get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") ;; *'container'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h change-jdk exec get-ip-addresses get-properties kill kill-all logs pause recreate restart resume set-environment-variables ssh unpause")" -- "$cur") ;; - *'open-docs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") - ;; - *'run'*'--file') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") ;; + *'ec2 start'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + ;; + + *'open-docs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") + ;; + *'connector'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create-or-update delete log-level logs offsets open-ccloud-connector-in-browser open-docs pause plugins restart resume select-config show-config show-config-parameters show-lag snippets status stop unpause update versions")" -- "$cur") ;; @@ -1228,10 +1236,6 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h break close-all-connection-with-error close-connection delay get-connections start toggle-accept-connections toggle-reads-client toggle-reads-service toggle-writes-client toggle-writes-service")" -- "$cur") ;; - *'ec2 start'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") - ;; - *'run'*'--tag') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") ;; @@ -1256,43 +1260,43 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h delete get get-compatibility get-mode register set-compatibility set-mode set-normalize")" -- "$cur") ;; - *'status'*) + *'re-run'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; + *'open'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") + ;; + *'config'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h check-repo-version clipboard container-kill-all-before-run editor folder_zip_or_jar open-ccloud-connector-in-browser")" -- "$cur") ;; - *'re-run'*) + *'status'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'open'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") - ;; - - *'tools'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h certs-create install-vscode-extension read-avro-file read-parquet-file")" -- "$cur") + *'topic'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter consume create delete describe display-consumer-offsets get-number-records list produce set-schema-compatibility")" -- "$cur") ;; - *'debug'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h block-traffic enable-remote-debugging flight-recorder generate-diagnostics heap-dump java-debug log-level tcp-dump testssl thread-dump")" -- "$cur") + *'run'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") ;; *'repro'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h bootstrap export import")" -- "$cur") ;; - *'run'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") + *'debug'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h block-traffic enable-remote-debugging flight-recorder generate-diagnostics heap-dump java-debug log-level tcp-dump testssl thread-dump")" -- "$cur") ;; - *'topic'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter consume create delete describe display-consumer-offsets get-number-records list produce set-schema-compatibility")" -- "$cur") + *'tools'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h certs-create install-vscode-extension read-avro-file read-parquet-file")" -- "$cur") ;; - *'stop'*) + *'help'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -1300,24 +1304,24 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'help'*) + *'stop'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'ec2'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create delete list open start stop sync-repro-folder")" -- "$cur") - ;; - *'run'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--cluster-cloud --cluster-creds --cluster-environment --cluster-name --cluster-region --cluster-schema-registry-creds --cluster-type --connector-jar --connector-tag --connector-zip --enable-conduktor --enable-control-center --enable-flink --enable-jmx-grafana --enable-kcat --enable-ksqldb --enable-multiple-brokers --enable-multiple-connect-workers --enable-rest-proxy --enable-sql-datagen --environment --file --help --open --tag -f -h -o")" -- "$cur") ;; + *'ec2'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create delete list open start stop sync-repro-folder")" -- "$cur") + ;; + *'-o') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") ;; *) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --output-level --version --vvv -h -o -v cleanup-cloud-details cleanup-cloud-resources config connector connector-plugin container debug ec2 get-docker-compose get-jmx-metrics help history open open-docs re-run remove-all-docker-images repro run schema status stop switch-back switch-ccloud tcp-proxy tools topic update-version")" -- "$cur") + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --output-level --version --vvv -h -o -v cleanup-cloud-details cleanup-cloud-resources config connector connector-plugin container debug ec2 get-ci-result get-docker-compose get-jmx-metrics help history open open-docs re-run remove-all-docker-images repro run schema status stop switch-back switch-ccloud tcp-proxy tools topic update-version")" -- "$cur") ;; esac diff --git a/scripts/cli/playground b/scripts/cli/playground index 126913555b..a8f5321ab3 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -33,6 +33,7 @@ playground_usage() { printf "%s\n" "$(bold "== Commands ==")" printf " %s Show help about a command\n" "$(green "help") " printf " %s 🗺️ Show a status\n" "$(green "status") " + printf " %s get ci result for current test\n" "$(green "get-ci-result") " printf " %s ⚙️ Configure CLI\n" "$(green "config") " echo printf "%s\n" "$(bold "Run commands:")" diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index 34ac53c786..e14f956bee 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -19,6 +19,13 @@ "options": [], "subcommands": null }, + { + "name": "get-ci-result", + "description": "get ci result for current test\n", + "usage": "playground get-ci-result", + "options": [], + "subcommands": null + }, { "name": "config", "description": "⚙️ Configure CLI\n", diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index b66bed7c93..a030e0cdb5 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -19,6 +19,12 @@ subcommands: usage: playground status options: [] subcommands: + - name: get-ci-result + description: | + get ci result for current test + usage: playground get-ci-result + options: [] + subcommands: - name: config description: | ⚙️ Configure CLI diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index 88fcd940c6..21b8c79233 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -245,7 +245,6 @@ commands: - name: get-ci-result help: get ci result for current test - private: true - name: bashly-reload private: true From 04fc1333fb6e555af78f94c3fb245c93d7f0b7a0 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 14 Jan 2025 13:30:52 +0100 Subject: [PATCH 153/659] wip --- scripts/cli/completions.bash | 210 ++++++++--------- scripts/cli/confluent-hub-plugin-list.txt | 1 - scripts/cli/playground | 260 +++++++++++----------- scripts/cli/playground.json | 14 +- scripts/cli/playground.yaml | 12 +- scripts/cli/src/bashly.yml | 7 +- 6 files changed, 252 insertions(+), 252 deletions(-) diff --git a/scripts/cli/completions.bash b/scripts/cli/completions.bash index 2b0dbcf515..67954c2481 100644 --- a/scripts/cli/completions.bash +++ b/scripts/cli/completions.bash @@ -72,14 +72,14 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; - *'connector open-ccloud-connector-in-browser'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - *'connector offsets get-offsets-request-status'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; + *'connector open-ccloud-connector-in-browser'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + *'tcp-proxy toggle-reads-client'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; @@ -444,14 +444,14 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug generate-diagnostics'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") - ;; - *'container pause'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'debug generate-diagnostics'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + ;; + *'topic consume'*'--key-subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; @@ -516,8 +516,8 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'config check-repo-version'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'ec2 create'*'--instance-type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "c1.medium c1.xlarge c3.2xlarge c3.4xlarge c3.8xlarge c3.large c3.xlarge c4.2xlarge c4.4xlarge c4.large c4.xlarge m1.large m1.medium m1.small m1.xlarge m2.2xlarge m2.4xlarge m2.xlarge m3.2xlarge m3.large m3.medium m3.xlarge m4.10xlarge m4.2xlarge m4.4xlarge m4.large m4.xlarge t1.micro t2.large t2.medium t2.micro t2.nano t2.small t3.2xlarge")" -- "$cur") ;; *'tools read-parquet-file'*'-f') @@ -532,16 +532,16 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'ec2 create'*'--instance-type') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "c1.medium c1.xlarge c3.2xlarge c3.4xlarge c3.8xlarge c3.large c3.xlarge c4.2xlarge c4.4xlarge c4.large c4.xlarge m1.large m1.medium m1.small m1.xlarge m2.2xlarge m2.4xlarge m2.xlarge m3.2xlarge m3.large m3.medium m3.xlarge m4.10xlarge m4.2xlarge m4.4xlarge m4.large m4.xlarge t1.micro t2.large t2.medium t2.micro t2.nano t2.small t3.2xlarge")" -- "$cur") + *'connector select-config'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'connector-plugin versions'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-plugin --force-refresh --help --last -c -h")" -- "$cur") ;; - *'connector select-config'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'config check-repo-version'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'schema set-compatibility'*) @@ -584,14 +584,14 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-environment-list "$cur")")" -- "$cur") ;; - *'config folder_zip_or_jar'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'topic get-number-records'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") ;; + *'config folder_zip_or_jar'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + *'topic produce'*'--reference') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; @@ -604,14 +604,14 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'cleanup-cloud-resources'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--force --help --resource -h")" -- "$cur") - ;; - *'connector show-config'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; + *'cleanup-cloud-resources'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--force --help --resource -h")" -- "$cur") + ;; + *'tools read-parquet-file'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; @@ -948,8 +948,8 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") ;; - *'run'*'--environment') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") + *'connector update'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") ;; *'container logs'*'-c') @@ -960,8 +960,8 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector update'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") + *'run'*'--environment') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") ;; *'container resume'*) @@ -1016,72 +1016,76 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--custom-smt --description --file --help --pipeline -d -f -h")" -- "$cur") ;; - *'schema register'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --metadata-property --schema --subject --verbose -h -v")" -- "$cur") - ;; - - *'schema get-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") + *'container pause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; *'container ssh'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'schema set-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") + *'debug heap-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") ;; - *'container pause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'topic produce'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'debug log-level'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h get set")" -- "$cur") ;; - *'tcp-proxy start'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --delay-service-response --help --hostname --port --service-response-corrupt --skip-automatic-connector-config --throttle-service-response -h")" -- "$cur") + *'topic consume'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'tcp-proxy delay'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") + *'tcp-proxy break'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") ;; - *'topic produce'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'tcp-proxy delay'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") ;; - *'tcp-proxy break'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") + *'tcp-proxy start'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --delay-service-response --help --hostname --port --service-response-corrupt --skip-automatic-connector-config --throttle-service-response -h")" -- "$cur") ;; *'get-jmx-metrics'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --domain --help --open -c -d -h -o")" -- "$cur") ;; - *'container ssh'*'-s') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") + *'schema set-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") ;; - *'topic consume'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'schema get-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; - *'debug heap-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") + *'schema register'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --metadata-property --schema --subject --verbose -h -v")" -- "$cur") ;; - *'repro import'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") + *'container ssh'*'-s') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") + ;; + + *'connector logs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") + ;; + + *'topic describe'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") ;; *'update-version'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-jar --connector-tag --connector-zip --help --tag -h")" -- "$cur") ;; - *'debug tcp-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --duration --help --port -c -h")" -- "$cur") + *'container logs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") ;; *'container kill'*) @@ -1092,112 +1096,108 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--command --container --help --root --shell -c -h")" -- "$cur") ;; - *'topic delete'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'debug tcp-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --duration --help --port -c -h")" -- "$cur") ;; *'connector stop'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'connector logs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") - ;; - - *'container logs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") - ;; - - *'topic describe'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") + *'repro import'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") ;; - *'topic produce'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --max-nb-messages-to-generate --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") + *'topic delete'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'switch-ccloud'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'--output-level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") ;; - *'container ssh'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") + *'schema delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --permanent --subject --verbose --version -h -v")" -- "$cur") ;; *'topic consume'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--grep --help --key-subject --max-characters --max-messages --min-expected-messages --plot-latencies-timestamp-field --tail --timeout --topic --value-subject --verbose -h -t -v")" -- "$cur") ;; - *'config editor'*) + *'get-ci-result'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'--output-level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") + *'switch-ccloud'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'schema delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --permanent --subject --verbose --version -h -v")" -- "$cur") + *'container ssh'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") ;; - *'get-ci-result'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'topic alter'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'debug testssl'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'topic alter'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'config editor'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'topic delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --skip-delete-schema --topic --verbose -h -t -v")" -- "$cur") + *'topic produce'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --max-nb-messages-to-generate --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") ;; - *'topic create'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --nb-partitions --topic --verbose -h -t -v")" -- "$cur") + *'ec2 delete'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") + ;; + + *'repro export'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help -h")" -- "$cur") ;; *'repro import'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'repro export'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help -h")" -- "$cur") + *'topic delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --skip-delete-schema --topic --verbose -h -t -v")" -- "$cur") ;; - *'ec2 delete'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") + *'topic create'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --nb-partitions --topic --verbose -h -t -v")" -- "$cur") ;; *'switch-back'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'topic alter'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") - ;; - *'ec2 start'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; + *'topic alter'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") + ;; + *'ec2 open'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'ec2 delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + *'ec2 create'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance-type --size --suffix -h")" -- "$cur") ;; *'topic list'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'ec2 create'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance-type --size --suffix -h")" -- "$cur") + *'ec2 delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; *'open'*'--file') @@ -1236,14 +1236,14 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h break close-all-connection-with-error close-connection delay get-connections start toggle-accept-connections toggle-reads-client toggle-reads-service toggle-writes-client toggle-writes-service")" -- "$cur") ;; - *'run'*'--tag') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") - ;; - *'ec2 list'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; + *'run'*'--tag') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") + ;; + *'ec2 stop'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; @@ -1308,14 +1308,14 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'run'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--cluster-cloud --cluster-creds --cluster-environment --cluster-name --cluster-region --cluster-schema-registry-creds --cluster-type --connector-jar --connector-tag --connector-zip --enable-conduktor --enable-control-center --enable-flink --enable-jmx-grafana --enable-kcat --enable-ksqldb --enable-multiple-brokers --enable-multiple-connect-workers --enable-rest-proxy --enable-sql-datagen --environment --file --help --open --tag -f -h -o")" -- "$cur") - ;; - *'ec2'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create delete list open start stop sync-repro-folder")" -- "$cur") ;; + *'run'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--cluster-cloud --cluster-creds --cluster-environment --cluster-name --cluster-region --cluster-schema-registry-creds --cluster-type --connector-jar --connector-tag --connector-zip --enable-conduktor --enable-control-center --enable-flink --enable-jmx-grafana --enable-kcat --enable-ksqldb --enable-multiple-brokers --enable-multiple-connect-workers --enable-rest-proxy --enable-sql-datagen --environment --file --help --open --tag -f -h -o")" -- "$cur") + ;; + *'-o') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") ;; diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index f107cac00c..4152728bc8 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -82,7 +82,6 @@ confluentinc/kafka-connect-mqtt confluentinc/kafka-connect-netezza confluentinc/kafka-connect-omnisci confluentinc/kafka-connect-oracle-cdc -confluentinc/kafka-connect-oracle-xstream-cdc-source confluentinc/kafka-connect-pagerduty confluentinc/kafka-connect-pinecone-sink confluentinc/kafka-connect-pivotal-gemfire diff --git a/scripts/cli/playground b/scripts/cli/playground index a8f5321ab3..17587cac4d 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -33,12 +33,12 @@ playground_usage() { printf "%s\n" "$(bold "== Commands ==")" printf " %s Show help about a command\n" "$(green "help") " printf " %s 🗺️ Show a status\n" "$(green "status") " - printf " %s get ci result for current test\n" "$(green "get-ci-result") " printf " %s ⚙️ Configure CLI\n" "$(green "config") " echo printf "%s\n" "$(bold "Run commands:")" printf " %s 🕹️ Run any example !\n" "$(green "run") " printf " %s ⚡ Simply re-run last example you ran with \n" "$(green "re-run") " + printf " %s 🤖 get CI result for current example\n" "$(green "get-ci-result") " printf " %s 🏰 Get an history of the examples which were run with run command and run it again\n" "$(green "history") " printf " %s 🌩️ Switch to ccloud environment.\n" "$(green "switch-ccloud") " printf " %s 💺 Switch back from previous environment before switch-ccloud was called.\n" "$(green "switch-back") " @@ -963,27 +963,6 @@ playground_update_docs_usage() { fi } -# :command.usage -playground_get_ci_result_usage() { - printf "playground get-ci-result - get ci result for current test\n\n" - - printf "%s\n" "$(bold "== Usage ==")" - printf " playground get-ci-result\n" - printf " playground get-ci-result --help | -h\n" - echo - - # :command.long_usage - if [[ -n "$long_usage" ]]; then - printf "%s\n" "$(bold "== Options ==")" - - # :command.usage_fixed_flags - printf " %s\n" "$(magenta "--help, -h")" - printf " Show this help\n" - echo - - fi -} - # :command.usage playground_bashly_reload_usage() { printf "playground bashly-reload\n\n" @@ -1765,6 +1744,27 @@ playground_re_run_usage() { fi } +# :command.usage +playground_get_ci_result_usage() { + printf "playground get-ci-result - 🤖 get CI result for current example\n\n" + + printf "%s\n" "$(bold "== Usage ==")" + printf " playground get-ci-result\n" + printf " playground get-ci-result --help | -h\n" + echo + + # :command.long_usage + if [[ -n "$long_usage" ]]; then + printf "%s\n" "$(bold "== Options ==")" + + # :command.usage_fixed_flags + printf " %s\n" "$(magenta "--help, -h")" + printf " Show this help\n" + echo + + fi +} + # :command.usage playground_history_usage() { printf "playground history - 🏰 Get an history of the examples which were run with run command and run it again\n\n" @@ -13412,61 +13412,6 @@ playground_update_docs_command() { mv ${root_folder}/scripts/cli/docs/* ${root_folder}/docs/ } -# :command.function -playground_get_ci_result_command() { - # src/commands/get-ci-result.sh - test_file=$(playground state get run.test_file) - - if [ ! -f $test_file ] - then - - logerror "File $test_file retrieved from $root_folder/playground.ini does not exist!" - exit 1 - fi - - test_file_directory="$(dirname "${test_file}")" - base1="${test_file_directory##*/}" # connect-cdc-oracle12-source - dir1="${test_file_directory%/*}" #connect - dir2="${dir1##*/}/$base1" # connect/connect-cdc-oracle12-source - - tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) - if [ -z "$PG_VERBOSE_MODE" ] - then - trap 'rm -rf $tmp_dir' EXIT - else - log "🐛📂 not deleting tmp dir $tmp_dir" - fi - - if [[ "$dir2" == reproduction-models* ]] - then - exit 0 - fi - - content_file="$tmp_dir/content.md" - curl -s -o $content_file https://raw.githubusercontent.com/vdesabou/kafka-docker-playground-docs/main/docs/content.md - - result_ok="$(grep "$dir2" $content_file | sed -n 's/.*\[CI \(ok\)\].*(\(https[^)]*\)).*/🤖CI status: 🟢 ok\n🔗test url: \2/p')" - result_fail="$(grep "$dir2" $content_file | sed -n 's/.*\[CI \(fail\)\].*(\(https[^)]*\)).*/🤖CI status: 🔴 fail\n🐛 github issue: \2/p')" - result_not_tested="$(grep "$dir2" $content_file | sed -n 's/.*\[not tested\].*/🤖CI status: 🤷‍♂️ not tested/p')" - - # print only result not empty - if [ -n "$result_ok" ] - then - log "$result_ok" - fi - - if [ -n "$result_fail" ] - then - logwarn "$result_fail" - check_if_continue - fi - - if [ -n "$result_not_tested" ] - then - log "$result_not_tested" - fi -} - # :command.function playground_bashly_reload_command() { # src/commands/bashly-reload.sh @@ -15297,6 +15242,61 @@ playground_re_run_command() { playground run -f "$test_file" $flag_list --force-interactive-re-run } +# :command.function +playground_get_ci_result_command() { + # src/commands/get-ci-result.sh + test_file=$(playground state get run.test_file) + + if [ ! -f $test_file ] + then + + logerror "File $test_file retrieved from $root_folder/playground.ini does not exist!" + exit 1 + fi + + test_file_directory="$(dirname "${test_file}")" + base1="${test_file_directory##*/}" # connect-cdc-oracle12-source + dir1="${test_file_directory%/*}" #connect + dir2="${dir1##*/}/$base1" # connect/connect-cdc-oracle12-source + + tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) + if [ -z "$PG_VERBOSE_MODE" ] + then + trap 'rm -rf $tmp_dir' EXIT + else + log "🐛📂 not deleting tmp dir $tmp_dir" + fi + + if [[ "$dir2" == reproduction-models* ]] + then + exit 0 + fi + + content_file="$tmp_dir/content.md" + curl -s -o $content_file https://raw.githubusercontent.com/vdesabou/kafka-docker-playground-docs/main/docs/content.md + + result_ok="$(grep "$dir2" $content_file | sed -n 's/.*\[CI \(ok\)\].*(\(https[^)]*\)).*/🤖CI status: 🟢 ok\n🔗test url: \2/p')" + result_fail="$(grep "$dir2" $content_file | sed -n 's/.*\[CI \(fail\)\].*(\(https[^)]*\)).*/🤖CI status: 🔴 fail\n🐛 github issue: \2/p')" + result_not_tested="$(grep "$dir2" $content_file | sed -n 's/.*\[not tested\].*/🤖CI status: 🤷‍♂️ not tested/p')" + + # print only result not empty + if [ -n "$result_ok" ] + then + log "$result_ok" + fi + + if [ -n "$result_fail" ] + then + logwarn "$result_fail" + check_if_continue + fi + + if [ -n "$result_not_tested" ] + then + log "$result_not_tested" + fi +} + # :command.function playground_history_command() { # src/commands/history.sh @@ -25789,13 +25789,6 @@ parse_requirements() { shift $# ;; - get-ci-result) - action="get-ci-result" - shift - playground_get_ci_result_parse_requirements "$@" - shift $# - ;; - bashly-reload) action="bashly-reload" shift @@ -25831,6 +25824,13 @@ parse_requirements() { shift $# ;; + get-ci-result) + action="get-ci-result" + shift + playground_get_ci_result_parse_requirements "$@" + shift $# + ;; + history) action="history" shift @@ -27486,51 +27486,6 @@ playground_update_docs_parse_requirements() { } -# :command.parse_requirements -playground_get_ci_result_parse_requirements() { - # :command.fixed_flags_filter - while [[ $# -gt 0 ]]; do - key="$1" - case "$key" in - --help | -h) - long_usage=yes - playground_get_ci_result_usage - exit - ;; - - *) - break - ;; - - esac - done - - # :command.command_filter - action="get-ci-result" - - # :command.parse_requirements_while - while [[ $# -gt 0 ]]; do - key="$1" - case "$key" in - - -?*) - printf "invalid option: %s\n" "$key" >&2 - exit 1 - ;; - - *) - # :command.parse_requirements_case - # :command.parse_requirements_case_simple - printf "invalid argument: %s\n" "$key" >&2 - exit 1 - - ;; - - esac - done - -} - # :command.parse_requirements playground_bashly_reload_parse_requirements() { # :command.fixed_flags_filter @@ -29179,6 +29134,51 @@ playground_re_run_parse_requirements() { } +# :command.parse_requirements +playground_get_ci_result_parse_requirements() { + # :command.fixed_flags_filter + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + --help | -h) + long_usage=yes + playground_get_ci_result_usage + exit + ;; + + *) + break + ;; + + esac + done + + # :command.command_filter + action="get-ci-result" + + # :command.parse_requirements_while + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; + + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + printf "invalid argument: %s\n" "$key" >&2 + exit 1 + + ;; + + esac + done + +} + # :command.parse_requirements playground_history_parse_requirements() { # :command.fixed_flags_filter @@ -39816,7 +39816,6 @@ run() { "get-predefined-schemas") playground_get_predefined_schemas_command ;; "update-readme") playground_update_readme_command ;; "update-docs") playground_update_docs_command ;; - "get-ci-result") playground_get_ci_result_command ;; "bashly-reload") playground_bashly_reload_command ;; "state") playground_state_command ;; "state show") playground_state_show_command ;; @@ -39837,6 +39836,7 @@ run() { "config check-repo-version") playground_config_check_repo_version_command ;; "run") playground_run_command ;; "re-run") playground_re_run_command ;; + "get-ci-result") playground_get_ci_result_command ;; "history") playground_history_command ;; "start-environment") playground_start_environment_command ;; "switch-ccloud") playground_switch_ccloud_command ;; diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index e14f956bee..16be5a0587 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -19,13 +19,6 @@ "options": [], "subcommands": null }, - { - "name": "get-ci-result", - "description": "get ci result for current test\n", - "usage": "playground get-ci-result", - "options": [], - "subcommands": null - }, { "name": "config", "description": "⚙️ Configure CLI\n", @@ -297,6 +290,13 @@ "options": [], "subcommands": null }, + { + "name": "get-ci-result", + "description": "🤖 get CI result for current example\n", + "usage": "playground get-ci-result", + "options": [], + "subcommands": null + }, { "name": "history", "description": "🏰 Get an history of the examples which were run with run command and run it again\n", diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index a030e0cdb5..8d2f0e7969 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -19,12 +19,6 @@ subcommands: usage: playground status options: [] subcommands: - - name: get-ci-result - description: | - get ci result for current test - usage: playground get-ci-result - options: [] - subcommands: - name: config description: | ⚙️ Configure CLI @@ -394,6 +388,12 @@ subcommands: usage: playground re-run options: [] subcommands: + - name: get-ci-result + description: | + 🤖 get CI result for current example + usage: playground get-ci-result + options: [] + subcommands: - name: history description: | 🏰 Get an history of the examples which were run with run command and run it again diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index 21b8c79233..b5bc85116d 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -243,9 +243,6 @@ commands: - name: update-docs private: true -- name: get-ci-result - help: get ci result for current test - - name: bashly-reload private: true dependencies: @@ -757,6 +754,10 @@ commands: examples: - playground re-run (interactive mode) +- name: get-ci-result + group: Run + help: 🤖 get CI result for current example + - name: history group: Run help: |- From 9cd49a7dadf5995ea3830390e57aa23fd9074394 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 15 Jan 2025 12:26:35 +0100 Subject: [PATCH 154/659] =?UTF-8?q?=F0=9F=A7=A0=20issue=20when=20playgroun?= =?UTF-8?q?d=20CLI=20is=20not=20in=20PATH=20#6204?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/src/lib/utils_function.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 7b98170b32..cd19f20ba1 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -4002,7 +4002,16 @@ function playground() { verbose_begin if [[ $(type -f playground 2>&1) =~ "not found" ]] then - ../../scripts/cli/playground "$@" + if [ -f ../../scripts/cli/playground ] + then + ../../scripts/cli/playground "$@" + elif [ -f ../../../scripts/cli/playground ] + then + ../../../scripts/cli/playground "$@" + else + logerror "🔍 playground command not found, add it to your PATH https://kafka-docker-playground.io/#/cli?id=🦶-setup-path" + exit 1 + fi else $(which playground) "$@" fi From f70a0905a38d3dc546067b487115b2c0f0b08a62 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 15 Jan 2025 12:29:58 +0100 Subject: [PATCH 155/659] =?UTF-8?q?=F0=9F=A7=A0=20flink=5Fconnectors=20var?= =?UTF-8?q?iable=20warnings=20during=20playground=20stop=20#6205?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 12 +++++++++++- scripts/cli/src/commands/stop.sh | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 17587cac4d..9b982f4a4f 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -12103,7 +12103,16 @@ function playground() { verbose_begin if [[ $(type -f playground 2>&1) =~ "not found" ]] then - ../../scripts/cli/playground "$@" + if [ -f ../../scripts/cli/playground ] + then + ../../scripts/cli/playground "$@" + elif [ -f ../../../scripts/cli/playground ] + then + ../../../scripts/cli/playground "$@" + else + logerror "🔍 playground command not found, add it to your PATH https://kafka-docker-playground.io/#/cli?id=🦶-setup-path" + exit 1 + fi else $(which playground) "$@" fi @@ -15956,6 +15965,7 @@ playground_stop_command() { logerror "File $test_file retrieved from $root_folder/playground.ini does not exist!" exit 1 fi + export flink_connectors="" filename=$(basename -- "$test_file") test_file_directory="$(dirname "${test_file}")" diff --git a/scripts/cli/src/commands/stop.sh b/scripts/cli/src/commands/stop.sh index f43d63702f..f0ab36f94c 100644 --- a/scripts/cli/src/commands/stop.sh +++ b/scripts/cli/src/commands/stop.sh @@ -5,6 +5,7 @@ then logerror "File $test_file retrieved from $root_folder/playground.ini does not exist!" exit 1 fi +export flink_connectors="" filename=$(basename -- "$test_file") test_file_directory="$(dirname "${test_file}")" From fa642cfc0c828bcb016f21fded6ff82acbccc10c Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 15 Jan 2025 14:10:06 +0100 Subject: [PATCH 156/659] fix for CP_CONNECT_IMAGE --- scripts/cli/playground | 11 +++++++---- scripts/cli/src/lib/utils_function.sh | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 9b982f4a4f..5862f72364 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8913,11 +8913,14 @@ function get_connect_image() { fi fi - if version_gt $CONNECT_TAG 5.2.99 + if [ -z "$CP_CONNECT_IMAGE" ] then - CP_CONNECT_IMAGE=confluentinc/cp-server-connect-base - else - CP_CONNECT_IMAGE=confluentinc/cp-kafka-connect-base + if version_gt $CONNECT_TAG 5.2.99 + then + CP_CONNECT_IMAGE=confluentinc/cp-server-connect-base + else + CP_CONNECT_IMAGE=confluentinc/cp-kafka-connect-base + fi fi } diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index cd19f20ba1..29888a5d50 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -743,11 +743,14 @@ function get_connect_image() { fi fi - if version_gt $CONNECT_TAG 5.2.99 + if [ -z "$CP_CONNECT_IMAGE" ] then - CP_CONNECT_IMAGE=confluentinc/cp-server-connect-base - else - CP_CONNECT_IMAGE=confluentinc/cp-kafka-connect-base + if version_gt $CONNECT_TAG 5.2.99 + then + CP_CONNECT_IMAGE=confluentinc/cp-server-connect-base + else + CP_CONNECT_IMAGE=confluentinc/cp-kafka-connect-base + fi fi } From 456ca3ff35a95d6a5000507d43b91cc8ee9a5e12 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 15 Jan 2025 14:26:06 +0100 Subject: [PATCH 157/659] fix for TAG --- scripts/cli/playground | 5 ++++- scripts/cli/src/lib/utils_function.sh | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 5862f72364..bc3516fcd5 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8904,7 +8904,10 @@ function get_connect_image() { set -e if [ "$CONNECT_TAG" == "" ] then - CONNECT_TAG=$(grep "export TAG" $root_folder/scripts/utils.sh | head -1 | cut -d "=" -f 2 | cut -d " " -f 1) + if [ -z "$TAG" ] + then + CONNECT_TAG=$(grep "export TAG" $root_folder/scripts/utils.sh | head -1 | cut -d "=" -f 2 | cut -d " " -f 1) + fi if [ "$CONNECT_TAG" == "" ] then diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 29888a5d50..de286ee96a 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -734,7 +734,10 @@ function get_connect_image() { set -e if [ "$CONNECT_TAG" == "" ] then - CONNECT_TAG=$(grep "export TAG" $root_folder/scripts/utils.sh | head -1 | cut -d "=" -f 2 | cut -d " " -f 1) + if [ -z "$TAG" ] + then + CONNECT_TAG=$(grep "export TAG" $root_folder/scripts/utils.sh | head -1 | cut -d "=" -f 2 | cut -d " " -f 1) + fi if [ "$CONNECT_TAG" == "" ] then From 01a2752750bbe0dc44816415a8a0b443a84b3ec2 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 15 Jan 2025 14:53:12 +0100 Subject: [PATCH 158/659] fix --- scripts/cli/playground | 2 ++ scripts/cli/src/lib/utils_function.sh | 2 ++ 2 files changed, 4 insertions(+) diff --git a/scripts/cli/playground b/scripts/cli/playground index bc3516fcd5..3c37b1078a 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8907,6 +8907,8 @@ function get_connect_image() { if [ -z "$TAG" ] then CONNECT_TAG=$(grep "export TAG" $root_folder/scripts/utils.sh | head -1 | cut -d "=" -f 2 | cut -d " " -f 1) + else + CONNECT_TAG=$TAG fi if [ "$CONNECT_TAG" == "" ] diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index de286ee96a..41cab8eddb 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -737,6 +737,8 @@ function get_connect_image() { if [ -z "$TAG" ] then CONNECT_TAG=$(grep "export TAG" $root_folder/scripts/utils.sh | head -1 | cut -d "=" -f 2 | cut -d " " -f 1) + else + CONNECT_TAG=$TAG fi if [ "$CONNECT_TAG" == "" ] From 295def93a9a912276abbd612894eec596210f1b7 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 15 Jan 2025 15:42:19 +0100 Subject: [PATCH 159/659] =?UTF-8?q?=F0=9F=A7=B9=20Add=20log.sensitive.data?= =?UTF-8?q?=20to=20all=20Oracle=20CDC=20examples=20#6206?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ccloud/fm-cdc-oracle11-source/README.md | 49 ------------------- connect/connect-cdc-oracle11-source/README.md | 1 + .../cdc-oracle11-source.sh | 1 + connect/connect-cdc-oracle12-source/README.md | 2 + .../cdc-oracle12-cdb-table-mtls-db-auth.sh | 1 + .../cdc-oracle12-cdb-table-mtls.sh | 1 + .../cdc-oracle12-cdb-table-ssl.sh | 1 + .../cdc-oracle12-cdb-table.sh | 1 + .../cdc-oracle12-pdb-table-mtls-db-auth.sh | 1 + .../cdc-oracle12-pdb-table-mtls.sh | 1 + .../cdc-oracle12-pdb-table-ssl.sh | 1 + .../cdc-oracle12-pdb-table.sh | 1 + connect/connect-cdc-oracle18-source/README.md | 2 + .../cdc-oracle18-cdb-table-mtls-db-auth.sh | 1 + .../cdc-oracle18-cdb-table-mtls.sh | 1 + .../cdc-oracle18-cdb-table-ssl.sh | 1 + .../cdc-oracle18-cdb-table.sh | 1 + .../cdc-oracle18-pdb-table-mtls.sh | 1 + .../cdc-oracle18-pdb-table-ssl.sh | 1 + .../cdc-oracle18-pdb-table.sh | 1 + connect/connect-cdc-oracle19-source/README.md | 2 + .../cdc-oracle19-cdb-table-mtls.sh | 1 + .../cdc-oracle19-cdb-table-ssl.sh | 1 + .../cdc-oracle19-cdb-table.sh | 1 + .../cdc-oracle19-pdb-mview.sh | 1 + .../cdc-oracle19-pdb-table-mtls-db-auth.sh | 1 + .../cdc-oracle19-pdb-table-mtls.sh | 1 + .../cdc-oracle19-pdb-table-ssl.sh | 1 + .../cdc-oracle19-pdb-table.sh | 1 + connect/connect-cdc-oracle21-source/README.md | 2 + .../cdc-oracle21-cdb-table-mtls-db-auth.sh | 1 + .../cdc-oracle21-cdb-table-mtls.sh | 1 + .../cdc-oracle21-cdb-table-ssl.sh | 1 + .../cdc-oracle21-cdb-table.sh | 1 + .../cdc-oracle21-pdb-mview.sh | 1 + .../cdc-oracle21-pdb-table-mtls-db-auth.sh | 1 + .../cdc-oracle21-pdb-table-mtls.sh | 1 + .../cdc-oracle21-pdb-table-ssl.sh | 1 + .../cdc-oracle21-pdb-table.sh | 1 + reproduction-models | 2 +- 40 files changed, 43 insertions(+), 50 deletions(-) diff --git a/ccloud/fm-cdc-oracle11-source/README.md b/ccloud/fm-cdc-oracle11-source/README.md index 9f35b7ae70..8255949a01 100644 --- a/ccloud/fm-cdc-oracle11-source/README.md +++ b/ccloud/fm-cdc-oracle11-source/README.md @@ -45,52 +45,3 @@ Using ksqlDB using CLI: ```bash $ docker exec -i ksqldb-cli ksql http://ksqldb-server:8088 ``` - -## Details of what the script is doing - -Create the source connector with: - -```bash -$ curl -X PUT \ - -H "Content-Type: application/json" \ - --data '{ - "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", - "tasks.max":2, - "key.converter": "io.confluent.connect.avro.AvroConverter", - "key.converter.schema.registry.url": "http://schema-registry:8081", - "value.converter": "io.confluent.connect.avro.AvroConverter", - "value.converter.schema.registry.url": "http://schema-registry:8081", - "confluent.license": "", - "confluent.topic.bootstrap.servers": "broker:9092", - "confluent.topic.replication.factor": "1", - "oracle.server": "oracle", - "oracle.port": 1521, - "oracle.sid": "XE", - "oracle.username": "MYUSER", - "oracle.password": "password", - "start.from":"snapshot", - "redo.log.topic.name": "redo-log-topic", - "redo.log.consumer.bootstrap.servers":"broker:9092", - "table.inclusion.regex": ".*CUSTOMERS.*", - "table.topic.name.template": "${databaseName}.${schemaName}.${tableName}", - "numeric.mapping": "best_fit", - "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1 - }' \ - http://localhost:8083/connectors/cdc-oracle11-source/config | jq . -``` - -Verify the topic `XE.MYUSER.CUSTOMERS`: - -```bash -playground topic consume --topic XE.MYUSER.CUSTOMERS --min-expected-messages 2 --timeout 60 -``` - -Results: - -```json -{"ID":"\u0001","FIRST_NAME":{"string":"Rica"},"LAST_NAME":{"string":"Blaisdell"},"EMAIL":{"string":"rblaisdell0@rambler.ru"},"GENDER":{"string":"Female"},"CLUB_STATUS":{"string":"bronze"},"COMMENTS":{"string":"Universal optimal hierarchy"},"CREATE_TS":{"long":1604047105216},"UPDATE_TS":{"long":1604047105000},"op_type":"R","table":"ORCLCDB.C##MYUSER.CUSTOMERS","scn":"1449498"} -{"ID":"\u0002","FIRST_NAME":{"string":"Ruthie"},"LAST_NAME":{"string":"Brockherst"},"EMAIL":{"string":"rbrockherst1@ow.ly"},"GENDER":{"string":"Female"},"CLUB_STATUS":{"string":"platinum"},"COMMENTS":{"string":"Reverse-engineered tangible interface"},"CREATE_TS":{"long":1604047105230},"UPDATE_TS":{"long":1604047105000},"op_type":"R","table":"ORCLCDB.C##MYUSER.CUSTOMERS","scn":"1449498"} -``` - -N.B: Control Center is reachable at [http://127.0.0.1:9021](http://127.0.0.1:9021]) diff --git a/connect/connect-cdc-oracle11-source/README.md b/connect/connect-cdc-oracle11-source/README.md index bea3c918f2..1df2774134 100644 --- a/connect/connect-cdc-oracle11-source/README.md +++ b/connect/connect-cdc-oracle11-source/README.md @@ -45,6 +45,7 @@ $ curl -X PUT \ -H "Content-Type: application/json" \ --data '{ "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle11-source/cdc-oracle11-source.sh b/connect/connect-cdc-oracle11-source/cdc-oracle11-source.sh index 45fb030da4..f015764834 100755 --- a/connect/connect-cdc-oracle11-source/cdc-oracle11-source.sh +++ b/connect/connect-cdc-oracle11-source/cdc-oracle11-source.sh @@ -81,6 +81,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle11-source --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max": 2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle12-source/README.md b/connect/connect-cdc-oracle12-source/README.md index 3367c0410f..2bfffed072 100644 --- a/connect/connect-cdc-oracle12-source/README.md +++ b/connect/connect-cdc-oracle12-source/README.md @@ -108,6 +108,7 @@ $ curl -X PUT \ -H "Content-Type: application/json" \ --data '{ "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", @@ -165,6 +166,7 @@ $ curl -X PUT \ -H "Content-Type: application/json" \ --data '{ "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls-db-auth.sh index 2c00e068d3..760d5fbc3a 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls-db-auth.sh @@ -213,6 +213,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh index a224ae0170..603408c94f 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh @@ -207,6 +207,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh index 63f12f0bff..c31ca0a8e4 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh @@ -179,6 +179,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table.sh index 296b0160fb..fc02f608a1 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table.sh @@ -116,6 +116,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh index 31678544b6..dd310fb6f2 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh @@ -229,6 +229,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh index 157db023b8..c4f04bd977 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh @@ -221,6 +221,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh index 0a7c9e1000..870f077444 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh @@ -191,6 +191,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table.sh index 8189adfde7..b8aac0593b 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table.sh @@ -128,6 +128,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle18-source/README.md b/connect/connect-cdc-oracle18-source/README.md index 99ed5f5356..c7b889197c 100644 --- a/connect/connect-cdc-oracle18-source/README.md +++ b/connect/connect-cdc-oracle18-source/README.md @@ -108,6 +108,7 @@ $ curl -X PUT \ -H "Content-Type: application/json" \ --data '{ "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", @@ -165,6 +166,7 @@ $ curl -X PUT \ -H "Content-Type: application/json" \ --data '{ "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls-db-auth.sh index 7ab2fc35e2..7b32960516 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls-db-auth.sh @@ -213,6 +213,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh index 5702f1705c..6b6db30896 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh @@ -209,6 +209,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh index 8e682cf74d..87b4be1eac 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh @@ -179,6 +179,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table.sh index be2fa38a85..314ba9f34f 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table.sh @@ -116,6 +116,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh index 5dfa5e6ad7..2c8d5e007c 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh @@ -221,6 +221,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh index 7d26caae7d..508ed8d1ac 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh @@ -191,6 +191,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table.sh index 12a17421de..6ffd313379 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table.sh @@ -128,6 +128,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle19-source/README.md b/connect/connect-cdc-oracle19-source/README.md index ff659e751c..9efc3fad14 100644 --- a/connect/connect-cdc-oracle19-source/README.md +++ b/connect/connect-cdc-oracle19-source/README.md @@ -102,6 +102,7 @@ $ curl -X PUT \ -H "Content-Type: application/json" \ --data '{ "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", @@ -160,6 +161,7 @@ $ curl -X PUT \ -H "Content-Type: application/json" \ --data '{ "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh index e8b6c5b33d..78daf6d146 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh @@ -202,6 +202,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":1, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh index e84accffac..7ae08f2c9a 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh @@ -175,6 +175,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":1, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh index aef37588f3..534b4cf991 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh @@ -113,6 +113,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-mview.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-mview.sh index a814e589d1..f7a9763948 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-mview.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-mview.sh @@ -115,6 +115,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb-mview --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh index 11f76ea4f4..63eeed487e 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh @@ -227,6 +227,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":1, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh index a33410df02..7732622e13 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh @@ -219,6 +219,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":1, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh index f078d199c3..c8a57bc444 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh @@ -191,6 +191,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":1, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh index 9503fb9162..0aa1edf7ef 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh @@ -129,6 +129,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle21-source/README.md b/connect/connect-cdc-oracle21-source/README.md index ee96bb73a7..a6b82e3d24 100644 --- a/connect/connect-cdc-oracle21-source/README.md +++ b/connect/connect-cdc-oracle21-source/README.md @@ -104,6 +104,7 @@ $ curl -X PUT \ -H "Content-Type: application/json" \ --data '{ "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", @@ -162,6 +163,7 @@ $ curl -X PUT \ -H "Content-Type: application/json" \ --data '{ "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh index 88323ba1fa..fcc1667019 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh @@ -210,6 +210,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":1, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh index f853d0949b..e4076a74a7 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh @@ -202,6 +202,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":1, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh index 4fbfe0b502..29417c851c 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh @@ -174,6 +174,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":1, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh index 8b6f22a2f8..38624f5cf3 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh @@ -113,6 +113,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-mview.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-mview.sh index 1bc19723f3..9e80ad78d5 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-mview.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-mview.sh @@ -115,6 +115,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb-mview --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh index 0c8674ecf9..150b067c67 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh @@ -227,6 +227,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":1, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh index 7face93c17..bdac42a2fd 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh @@ -219,6 +219,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":1, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh index 3c64893f19..57cfe5fc8c 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh @@ -191,6 +191,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":1, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table.sh index 981bd0375f..93a2a70b55 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table.sh @@ -129,6 +129,7 @@ log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", "tasks.max":2, "key.converter": "io.confluent.connect.avro.AvroConverter", "key.converter.schema.registry.url": "http://schema-registry:8081", diff --git a/reproduction-models b/reproduction-models index 6e1eafd192..e55594d5ce 160000 --- a/reproduction-models +++ b/reproduction-models @@ -1 +1 @@ -Subproject commit 6e1eafd192db686dd3c6d4ce97e631316356a697 +Subproject commit e55594d5ce21eb064776acdea37065e0649959b3 From 7ee50247f47206a1733753d5042307e3af33ea0f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 15 Jan 2025 16:20:12 +0100 Subject: [PATCH 160/659] remove "make sure to always use the CLI to run example" --- scripts/cli/playground | 16 +++++----------- scripts/cli/src/commands/state/del.sh | 4 +--- scripts/cli/src/commands/state/get.sh | 4 +--- scripts/cli/src/commands/state/set.sh | 4 ++-- scripts/cli/src/commands/state/show.sh | 4 +--- 5 files changed, 10 insertions(+), 22 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 3c37b1078a..c74a72c7df 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -13445,9 +13445,7 @@ playground_state_show_command() { # Using the standard library (lib/ini.sh) to show the entire config file if [ ! -f "$root_folder/playground.ini" ] then - logerror "$root_folder/playground.ini does not exist !" - logerror "Make sure to always use the CLI to run examples" - exit 1 + touch $root_folder/playground.ini fi ini_load $root_folder/playground.ini ini_show @@ -13459,9 +13457,7 @@ playground_state_get_command() { # Using the standard library (lib/ini.sh) to show a value from the config if [ ! -f "$root_folder/playground.ini" ] then - logerror "$root_folder/playground.ini does not exist !" - logerror "Make sure to always use the CLI to run examples" - exit 1 + touch $root_folder/playground.ini fi ini_load $root_folder/playground.ini @@ -13480,9 +13476,9 @@ playground_state_get_command() { playground_state_set_command() { # src/commands/state/set.sh # Using the standard library (lib/ini.sh) to store a value to the config - if [ ! -f $root_folder/playground.ini ] + if [ ! -f "$root_folder/playground.ini" ] then - touch $root_folder/playground.ini + touch $root_folder/playground.ini fi set -e ini_load $root_folder/playground.ini @@ -13500,9 +13496,7 @@ playground_state_del_command() { # Using the standard library (lib/ini.sh) to delete a value from the config if [ ! -f "$root_folder/playground.ini" ] then - logerror "$root_folder/playground.ini does not exist !" - logerror "Make sure to always use the CLI to run examples" - exit 1 + touch $root_folder/playground.ini fi set -e ini_load $root_folder/playground.ini diff --git a/scripts/cli/src/commands/state/del.sh b/scripts/cli/src/commands/state/del.sh index ffbdb932c2..dd593235f2 100644 --- a/scripts/cli/src/commands/state/del.sh +++ b/scripts/cli/src/commands/state/del.sh @@ -1,9 +1,7 @@ # Using the standard library (lib/ini.sh) to delete a value from the config if [ ! -f "$root_folder/playground.ini" ] then - logerror "$root_folder/playground.ini does not exist !" - logerror "Make sure to always use the CLI to run examples" - exit 1 + touch $root_folder/playground.ini fi set -e ini_load $root_folder/playground.ini diff --git a/scripts/cli/src/commands/state/get.sh b/scripts/cli/src/commands/state/get.sh index 3c4cdf8123..08be6e9dd3 100644 --- a/scripts/cli/src/commands/state/get.sh +++ b/scripts/cli/src/commands/state/get.sh @@ -1,9 +1,7 @@ # Using the standard library (lib/ini.sh) to show a value from the config if [ ! -f "$root_folder/playground.ini" ] then - logerror "$root_folder/playground.ini does not exist !" - logerror "Make sure to always use the CLI to run examples" - exit 1 + touch $root_folder/playground.ini fi ini_load $root_folder/playground.ini diff --git a/scripts/cli/src/commands/state/set.sh b/scripts/cli/src/commands/state/set.sh index ed53a05438..f33ca5d601 100644 --- a/scripts/cli/src/commands/state/set.sh +++ b/scripts/cli/src/commands/state/set.sh @@ -1,7 +1,7 @@ # Using the standard library (lib/ini.sh) to store a value to the config -if [ ! -f $root_folder/playground.ini ] +if [ ! -f "$root_folder/playground.ini" ] then - touch $root_folder/playground.ini + touch $root_folder/playground.ini fi set -e ini_load $root_folder/playground.ini diff --git a/scripts/cli/src/commands/state/show.sh b/scripts/cli/src/commands/state/show.sh index 71db6c5d4f..71b4f7f093 100644 --- a/scripts/cli/src/commands/state/show.sh +++ b/scripts/cli/src/commands/state/show.sh @@ -1,9 +1,7 @@ # Using the standard library (lib/ini.sh) to show the entire config file if [ ! -f "$root_folder/playground.ini" ] then - logerror "$root_folder/playground.ini does not exist !" - logerror "Make sure to always use the CLI to run examples" - exit 1 + touch $root_folder/playground.ini fi ini_load $root_folder/playground.ini ini_show \ No newline at end of file From da1eef229f8cc82e1aaee6f6fc7fdb930c35ae3c Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 16 Jan 2025 13:44:52 +0100 Subject: [PATCH 161/659] =?UTF-8?q?=F0=9F=91=BE=20AWS=20examples=20are=20n?= =?UTF-8?q?ot=20working=20with=20short-lived=20credentials=20#4894?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloudformation/dotfiles/zshrc | 1 - ...plaintext.proxy.with-assuming-iam-role.yml | 5 +- ...mpose.plaintext.with-assuming-iam-role.yml | 2 +- ...mpose.plaintext.with-short-lived-creds.yml | 8 - .../docker-compose.plaintext.yml | 3 + ...ole-with-custom-aws-credential-provider.sh | 37 +---- .../s3-sink-proxy-basic-auth.sh | 36 +---- .../s3-sink-proxy-with-assuming-iam-role.sh | 43 +----- connect/connect-aws-s3-sink/s3-sink-proxy.sh | 36 +---- .../s3-sink-with-assuming-iam-role-config.sh | 37 +---- .../s3-sink-with-assuming-iam-role.sh | 43 +----- .../s3-sink-with-short-lived-creds.sh | 138 ------------------ connect/connect-aws-s3-sink/s3-sink.sh | 53 +------ connect/connect-jdbc-mysql-sink/mysql-sink.sh | 3 +- scripts/cli/playground | 124 ++++++++++++++++ scripts/cli/src/lib/cli_function.sh | 8 + scripts/cli/src/lib/utils_function.sh | 115 +++++++++++++++ 17 files changed, 268 insertions(+), 424 deletions(-) delete mode 100644 connect/connect-aws-s3-sink/docker-compose.plaintext.with-short-lived-creds.yml delete mode 100755 connect/connect-aws-s3-sink/s3-sink-with-short-lived-creds.sh diff --git a/cloudformation/dotfiles/zshrc b/cloudformation/dotfiles/zshrc index c6a2d26ba1..8b57ce2ddd 100644 --- a/cloudformation/dotfiles/zshrc +++ b/cloudformation/dotfiles/zshrc @@ -120,7 +120,6 @@ if [ "$(whoami)" = "vsaboulin" ] then export ENABLE_CONTROL_CENTER=1 export C3_PORT=9022 - export AWS_CREDENTIALS_FILE_NAME="credentials" export CONNECT_CONTAINER_HOME_DIR="/home/appuser" cd ~/kafka-docker-playground set -o allexport;source secrets.properties;set +o allexport diff --git a/connect/connect-aws-s3-sink/docker-compose.plaintext.proxy.with-assuming-iam-role.yml b/connect/connect-aws-s3-sink/docker-compose.plaintext.proxy.with-assuming-iam-role.yml index 61b697c250..8310519ccc 100644 --- a/connect/connect-aws-s3-sink/docker-compose.plaintext.proxy.with-assuming-iam-role.yml +++ b/connect/connect-aws-s3-sink/docker-compose.plaintext.proxy.with-assuming-iam-role.yml @@ -11,9 +11,8 @@ services: connect: volumes: - - $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-s3 - AWS_REGION: $AWS_REGION - # \ No newline at end of file + AWS_REGION: $AWS_REGION \ No newline at end of file diff --git a/connect/connect-aws-s3-sink/docker-compose.plaintext.with-assuming-iam-role.yml b/connect/connect-aws-s3-sink/docker-compose.plaintext.with-assuming-iam-role.yml index 69bc6d9048..473206302c 100644 --- a/connect/connect-aws-s3-sink/docker-compose.plaintext.with-assuming-iam-role.yml +++ b/connect/connect-aws-s3-sink/docker-compose.plaintext.with-assuming-iam-role.yml @@ -2,7 +2,7 @@ services: connect: volumes: - - $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-s3 diff --git a/connect/connect-aws-s3-sink/docker-compose.plaintext.with-short-lived-creds.yml b/connect/connect-aws-s3-sink/docker-compose.plaintext.with-short-lived-creds.yml deleted file mode 100644 index 4d114ec188..0000000000 --- a/connect/connect-aws-s3-sink/docker-compose.plaintext.with-short-lived-creds.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -services: - connect: - volumes: - - $TMP_CREDENTIALS_FILE:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials - - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-s3 \ No newline at end of file diff --git a/connect/connect-aws-s3-sink/docker-compose.plaintext.yml b/connect/connect-aws-s3-sink/docker-compose.plaintext.yml index bf49b5c5d5..fbf6fffb26 100644 --- a/connect/connect-aws-s3-sink/docker-compose.plaintext.yml +++ b/connect/connect-aws-s3-sink/docker-compose.plaintext.yml @@ -1,5 +1,8 @@ --- services: connect: + volumes: + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-s3 \ No newline at end of file diff --git a/connect/connect-aws-s3-sink/s3-sink-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh b/connect/connect-aws-s3-sink/s3-sink-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh index 6f15f3c9a3..c59c21ca74 100755 --- a/connect/connect-aws-s3-sink/s3-sink-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh +++ b/connect/connect-aws-s3-sink/s3-sink-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh @@ -46,42 +46,7 @@ do set -e done - -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.yml" diff --git a/connect/connect-aws-s3-sink/s3-sink-proxy-basic-auth.sh b/connect/connect-aws-s3-sink/s3-sink-proxy-basic-auth.sh index a64edf3c08..d7cea8a250 100755 --- a/connect/connect-aws-s3-sink/s3-sink-proxy-basic-auth.sh +++ b/connect/connect-aws-s3-sink/s3-sink-proxy-basic-auth.sh @@ -4,41 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.proxy-basic-auth.yml" diff --git a/connect/connect-aws-s3-sink/s3-sink-proxy-with-assuming-iam-role.sh b/connect/connect-aws-s3-sink/s3-sink-proxy-with-assuming-iam-role.sh index 7feab51683..7a3ade1cf0 100755 --- a/connect/connect-aws-s3-sink/s3-sink-proxy-with-assuming-iam-role.sh +++ b/connect/connect-aws-s3-sink/s3-sink-proxy-with-assuming-iam-role.sh @@ -8,49 +8,14 @@ source ${DIR}/../../scripts/utils.sh logwarn "WARN: This is not working due to https://github.com/aws/aws-sdk-java/issues/2558" exit 111 -# this is only used for AWS CLI -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) +export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role +if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -export AWS_CREDENTIALS_FILE_NAME=credentials-with-assuming-iam-role -if [ ! -f $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME ] -then - logerror "ERROR: $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME is not set" + logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.proxy.with-assuming-iam-role.yml" diff --git a/connect/connect-aws-s3-sink/s3-sink-proxy.sh b/connect/connect-aws-s3-sink/s3-sink-proxy.sh index fa0a8ca17b..eb5380d1ef 100755 --- a/connect/connect-aws-s3-sink/s3-sink-proxy.sh +++ b/connect/connect-aws-s3-sink/s3-sink-proxy.sh @@ -4,41 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.proxy.yml" diff --git a/connect/connect-aws-s3-sink/s3-sink-with-assuming-iam-role-config.sh b/connect/connect-aws-s3-sink/s3-sink-with-assuming-iam-role-config.sh index 99c4a84dd3..ed4956944d 100755 --- a/connect/connect-aws-s3-sink/s3-sink-with-assuming-iam-role-config.sh +++ b/connect/connect-aws-s3-sink/s3-sink-with-assuming-iam-role-config.sh @@ -6,36 +6,6 @@ source ${DIR}/../../scripts/utils.sh AWS_STS_ROLE_ARN=${AWS_STS_ROLE_ARN:-$1} -# this is only used for AWS CLI -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - if [ -z "$AWS_STS_ROLE_ARN" ] then logerror "AWS_STS_ROLE_ARN is not set. Export it as environment variable or pass it as argument" @@ -54,12 +24,7 @@ then exit 1 fi -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials # credentials file is not mounted in connect container PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} diff --git a/connect/connect-aws-s3-sink/s3-sink-with-assuming-iam-role.sh b/connect/connect-aws-s3-sink/s3-sink-with-assuming-iam-role.sh index 175a7f9f09..3418a99572 100755 --- a/connect/connect-aws-s3-sink/s3-sink-with-assuming-iam-role.sh +++ b/connect/connect-aws-s3-sink/s3-sink-with-assuming-iam-role.sh @@ -4,49 +4,14 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -# this is only used for AWS CLI -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) +export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role +if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -export AWS_CREDENTIALS_FILE_NAME=credentials-with-assuming-iam-role -if [ ! -f $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME ] -then - logerror "ERROR: $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME is not set" + logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.with-assuming-iam-role.yml" diff --git a/connect/connect-aws-s3-sink/s3-sink-with-short-lived-creds.sh b/connect/connect-aws-s3-sink/s3-sink-with-short-lived-creds.sh deleted file mode 100755 index 9da4cca308..0000000000 --- a/connect/connect-aws-s3-sink/s3-sink-with-short-lived-creds.sh +++ /dev/null @@ -1,138 +0,0 @@ -#!/bin/bash -set -e - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -source ${DIR}/../../scripts/utils.sh - - -tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) -if [ -z "$PG_VERBOSE_MODE" ] -then - trap 'rm -rf $tmp_dir' EXIT -else - log "🐛📂 not deleting tmp dir $tmp_dir" -fi -export TMP_CREDENTIALS_FILE="$tmp_dir/credentials" - -if [ ! -z $AWS_ACCESS_KEY_ID ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ ! -z "$AWS_SESSION_TOKEN" ] -then - log "💭 Using environment variables AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - export AWS_SESSION_TOKEN - -cat << EOF > $TMP_CREDENTIALS_FILE -[default] -aws_access_key_id=$AWS_ACCESS_KEY_ID -aws_secret_access_key=$AWS_SECRET_ACCESS_KEY -aws_session_token=$AWS_SESSION_TOKEN -EOF -elif grep -q "aws_session_token" $HOME/.aws/credentials -then - head -4 $HOME/.aws/credentials > $TMP_CREDENTIALS_FILE - - set +e - grep -q default $TMP_CREDENTIALS_FILE - if [ $? != 0 ] - then - logerror "$HOME/.aws/credentials does not have expected format, the 4 first lines must be:" - echo "[default]" - echo "aws_access_key_id=" - echo "aws_secret_access_key=" - echo "aws_session_token=" - exit 1 - fi - grep -q aws_session_token $TMP_CREDENTIALS_FILE - if [ $? != 0 ] - then - logerror "$HOME/.aws/credentials does not have expected format, the 4 first lines must be:" - echo "[default]" - echo "aws_access_key_id=" - echo "aws_secret_access_key=" - echo "aws_session_token=" - exit 1 - fi - set +e -fi - -log "✨ Using credentials file $TMP_CREDENTIALS_FILE" - -if [ -z "$AWS_REGION" ] -then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi - -PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} -playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.with-short-lived-creds.yml" - -AWS_BUCKET_NAME=pg-bucket-${USER} -AWS_BUCKET_NAME=${AWS_BUCKET_NAME//[-.]/} - - -log "Create bucket <$AWS_BUCKET_NAME>, if required" -set +e -if [ "$AWS_REGION" == "us-east-1" ] -then - aws s3api create-bucket --bucket $AWS_BUCKET_NAME --region $AWS_REGION -else - aws s3api create-bucket --bucket $AWS_BUCKET_NAME --region $AWS_REGION --create-bucket-configuration LocationConstraint=$AWS_REGION -fi -set -e -log "Empty bucket <$AWS_BUCKET_NAME/$TAG>, if required" -set +e -aws s3 rm s3://$AWS_BUCKET_NAME/$TAG --recursive --region $AWS_REGION -set -e - -log "Creating S3 Sink connector with bucket name <$AWS_BUCKET_NAME>" -playground connector create-or-update --connector s3-sink << EOF -{ - "connector.class": "io.confluent.connect.s3.S3SinkConnector", - "tasks.max": "1", - "topics": "s3_topic", - "s3.region": "$AWS_REGION", - "s3.bucket.name": "$AWS_BUCKET_NAME", - "topics.dir": "$TAG", - "s3.part.size": "52428801", - "flush.size": "3", - "storage.class": "io.confluent.connect.s3.storage.S3Storage", - "format.class": "io.confluent.connect.s3.format.avro.AvroFormat", - "schema.compatibility": "NONE" -} -EOF - -log "Sending messages to topic s3_topic" -playground topic produce -t s3_topic --nb-messages 10 --forced-value '{"f1":"value%g"}' << 'EOF' -{ - "type": "record", - "name": "myrecord", - "fields": [ - { - "name": "f1", - "type": "string" - } - ] -} -EOF - -sleep 10 - -# log "Listing objects of in S3" -# aws s3api list-objects --bucket "$AWS_BUCKET_NAME" - -log "Getting one of the avro files locally and displaying content with avro-tools" -aws s3 cp --only-show-errors s3://$AWS_BUCKET_NAME/$TAG/s3_topic/partition=0/s3_topic+0+0000000000.avro s3_topic+0+0000000000.avro - -playground tools read-avro-file --file $PWD/s3_topic+0+0000000000.avro -rm -f s3_topic+0+0000000000.avro \ No newline at end of file diff --git a/connect/connect-aws-s3-sink/s3-sink.sh b/connect/connect-aws-s3-sink/s3-sink.sh index 8d6862bef8..4d231f3910 100755 --- a/connect/connect-aws-s3-sink/s3-sink.sh +++ b/connect/connect-aws-s3-sink/s3-sink.sh @@ -4,58 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ -z $AWS_SESSION_TOKEN ] -then - : -else - if [ ! -z $AWS_SESSION_TOKEN ] || grep -q "aws_session_token" $HOME/.aws/credentials - then - if [ ! -z $AWS_SESSION_TOKEN ] - then - logwarn "AWS_SESSION_TOKEN environment variable is set, running example s3-sink-with-short-lived-creds.sh" - else - logwarn "the file $HOME/.aws/credentials contains aws_session_token, running example s3-sink-with-short-lived-creds.sh" - fi - ./s3-sink-with-short-lived-creds.sh - exit 0 - fi -fi - -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" diff --git a/connect/connect-jdbc-mysql-sink/mysql-sink.sh b/connect/connect-jdbc-mysql-sink/mysql-sink.sh index 3b0336c2d7..1f2ce4c640 100755 --- a/connect/connect-jdbc-mysql-sink/mysql-sink.sh +++ b/connect/connect-jdbc-mysql-sink/mysql-sink.sh @@ -22,7 +22,8 @@ playground connector create-or-update --connector mysql-sink << EOF "tasks.max": "1", "connection.url": "jdbc:mysql://mysql:3306/db?user=user&password=password&useSSL=false", "topics": "orders", - "auto.create": "true" + "auto.create": "true", + "consumer.override.enable.auto.commit": "false" } EOF diff --git a/scripts/cli/playground b/scripts/cli/playground index c74a72c7df..aa5db92ccc 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -7191,6 +7191,14 @@ function add_connector_config_based_on_environment () { echo "$json_content" > $tmp_dir/1.json + if [ -n "$AWS_SHORT_LIVE_CREDENTIALS_USED" ] + then + log "💫 removing aws.access.key.id and aws.secret.access.key from config" + echo "$json_content" > $tmp_dir/input.json + jq 'del(.["aws.access.key.id"], .["aws.secret.access.key"])' $tmp_dir/input.json > $tmp_dir/output.json + json_content=$(cat $tmp_dir/output.json) + fi + case "${environment}" in plaintext) # nothing to do @@ -12391,6 +12399,122 @@ function maybe_set_azure_subscription () { fi } +function handle_aws_credentials () { + log "handle_aws_credentials" + if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ -z $AWS_SESSION_TOKEN ] + then + if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) + then + logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" + exit 1 + else + if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] + then + log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" + export AWS_ACCESS_KEY_ID + export AWS_SECRET_ACCESS_KEY + else + if [ -f $HOME/.aws/credentials ] + then + logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" + export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) + export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) + + fi + fi + if [ -z "$AWS_REGION" ] + then + AWS_REGION=$(aws configure get region | tr '\r' '\n') + if [ "$AWS_REGION" == "" ] + then + logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" + exit 1 + fi + fi + fi + else + if [ ! -z $AWS_SESSION_TOKEN ] || grep -q "aws_session_token" $HOME/.aws/credentials + then + if [ ! -z $AWS_SESSION_TOKEN ] + then + logwarn "AWS_SESSION_TOKEN environment variable is set, running example s3-sink-with-short-lived-creds.sh" + else + logwarn "the file $HOME/.aws/credentials contains aws_session_token, running example s3-sink-with-short-lived-creds.sh" + fi + + tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) + if [ -z "$PG_VERBOSE_MODE" ] + then + trap 'rm -rf $tmp_dir' EXIT + else + log "🐛📂 not deleting tmp dir $tmp_dir" + fi + export AWS_CREDENTIALS_FILE_NAME="$tmp_dir/credentials" + + if [ ! -z $AWS_ACCESS_KEY_ID ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ ! -z "$AWS_SESSION_TOKEN" ] + then + log "💭 Using environment variables AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN" + export AWS_ACCESS_KEY_ID + export AWS_SECRET_ACCESS_KEY + export AWS_SESSION_TOKEN + + cat << EOF > $AWS_CREDENTIALS_FILE_NAME + [default] + aws_access_key_id=$AWS_ACCESS_KEY_ID + aws_secret_access_key=$AWS_SECRET_ACCESS_KEY + aws_session_token=$AWS_SESSION_TOKEN +EOF + elif grep -q "aws_session_token" $HOME/.aws/credentials + then + head -4 $HOME/.aws/credentials > $AWS_CREDENTIALS_FILE_NAME + + set +e + grep -q default $AWS_CREDENTIALS_FILE_NAME + if [ $? != 0 ] + then + logerror "$HOME/.aws/credentials does not have expected format, the 4 first lines must be:" + echo "[default]" + echo "aws_access_key_id=" + echo "aws_secret_access_key=" + echo "aws_session_token=" + exit 1 + fi + grep -q aws_session_token $AWS_CREDENTIALS_FILE_NAME + if [ $? != 0 ] + then + logerror "$HOME/.aws/credentials does not have expected format, the 4 first lines must be:" + echo "[default]" + echo "aws_access_key_id=" + echo "aws_secret_access_key=" + echo "aws_session_token=" + exit 1 + fi + set +e + fi + + log "✨ Using AWS short live with credentials file $AWS_CREDENTIALS_FILE_NAME" + export AWS_SHORT_LIVE_CREDENTIALS_USED=1 + fi + fi + + if [ -z "$AWS_REGION" ] + then + AWS_REGION=$(aws configure get region | tr '\r' '\n') + if [ "$AWS_REGION" == "" ] + then + logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" + exit 1 + fi + fi + + if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" + then + export CONNECT_CONTAINER_HOME_DIR="/home/appuser" + else + export CONNECT_CONTAINER_HOME_DIR="/root" + fi +} + # src/lib/validations/validate_dir_exists.sh validate_dir_exists() { [[ -d "$1" ]] || logerror "<$1> must be an existing directory" diff --git a/scripts/cli/src/lib/cli_function.sh b/scripts/cli/src/lib/cli_function.sh index 372a69b934..19683fb235 100644 --- a/scripts/cli/src/lib/cli_function.sh +++ b/scripts/cli/src/lib/cli_function.sh @@ -814,6 +814,14 @@ function add_connector_config_based_on_environment () { echo "$json_content" > $tmp_dir/1.json + if [ -n "$AWS_SHORT_LIVE_CREDENTIALS_USED" ] + then + log "💫 removing aws.access.key.id and aws.secret.access.key from config" + echo "$json_content" > $tmp_dir/input.json + jq 'del(.["aws.access.key.id"], .["aws.secret.access.key"])' $tmp_dir/input.json > $tmp_dir/output.json + json_content=$(cat $tmp_dir/output.json) + fi + case "${environment}" in plaintext) # nothing to do diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 41cab8eddb..75aeb9fa27 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -4287,3 +4287,118 @@ function maybe_set_azure_subscription () { log "💎 AZURE_SUBSCRIPTION_NAME is not set, using default subscription $default_subscription" fi } + +function handle_aws_credentials () { + log "handle_aws_credentials" + if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ -z $AWS_SESSION_TOKEN ] + then + if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) + then + logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" + exit 1 + else + if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] + then + log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" + export AWS_ACCESS_KEY_ID + export AWS_SECRET_ACCESS_KEY + else + if [ -f $HOME/.aws/credentials ] + then + logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" + export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) + export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) + fi + fi + if [ -z "$AWS_REGION" ] + then + AWS_REGION=$(aws configure get region | tr '\r' '\n') + if [ "$AWS_REGION" == "" ] + then + logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" + exit 1 + fi + fi + fi + else + if [ ! -z $AWS_SESSION_TOKEN ] || grep -q "aws_session_token" $HOME/.aws/credentials + then + if [ ! -z $AWS_SESSION_TOKEN ] + then + logwarn "AWS_SESSION_TOKEN environment variable is set, running example s3-sink-with-short-lived-creds.sh" + else + logwarn "the file $HOME/.aws/credentials contains aws_session_token, running example s3-sink-with-short-lived-creds.sh" + fi + + tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) + if [ -z "$PG_VERBOSE_MODE" ] + then + trap 'rm -rf $tmp_dir' EXIT + else + log "🐛📂 not deleting tmp dir $tmp_dir" + fi + export AWS_CREDENTIALS_FILE_NAME="$tmp_dir/credentials" + + if [ ! -z $AWS_ACCESS_KEY_ID ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ ! -z "$AWS_SESSION_TOKEN" ] + then + log "💭 Using environment variables AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN" + export AWS_ACCESS_KEY_ID + export AWS_SECRET_ACCESS_KEY + export AWS_SESSION_TOKEN + + cat << EOF > $AWS_CREDENTIALS_FILE_NAME + [default] + aws_access_key_id=$AWS_ACCESS_KEY_ID + aws_secret_access_key=$AWS_SECRET_ACCESS_KEY + aws_session_token=$AWS_SESSION_TOKEN +EOF + elif grep -q "aws_session_token" $HOME/.aws/credentials + then + head -4 $HOME/.aws/credentials > $AWS_CREDENTIALS_FILE_NAME + + set +e + grep -q default $AWS_CREDENTIALS_FILE_NAME + if [ $? != 0 ] + then + logerror "$HOME/.aws/credentials does not have expected format, the 4 first lines must be:" + echo "[default]" + echo "aws_access_key_id=" + echo "aws_secret_access_key=" + echo "aws_session_token=" + exit 1 + fi + grep -q aws_session_token $AWS_CREDENTIALS_FILE_NAME + if [ $? != 0 ] + then + logerror "$HOME/.aws/credentials does not have expected format, the 4 first lines must be:" + echo "[default]" + echo "aws_access_key_id=" + echo "aws_secret_access_key=" + echo "aws_session_token=" + exit 1 + fi + set +e + fi + + log "✨ Using AWS short live with credentials file $AWS_CREDENTIALS_FILE_NAME" + export AWS_SHORT_LIVE_CREDENTIALS_USED=1 + fi + fi + + if [ -z "$AWS_REGION" ] + then + AWS_REGION=$(aws configure get region | tr '\r' '\n') + if [ "$AWS_REGION" == "" ] + then + logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" + exit 1 + fi + fi + + if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" + then + export CONNECT_CONTAINER_HOME_DIR="/home/appuser" + else + export CONNECT_CONTAINER_HOME_DIR="/root" + fi +} \ No newline at end of file From 5abf10321e2b90a24aa7a3b2aad9002171b98469 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 16 Jan 2025 14:12:54 +0100 Subject: [PATCH 162/659] =?UTF-8?q?=F0=9F=91=BE=20AWS=20examples=20are=20n?= =?UTF-8?q?ot=20working=20with=20short-lived=20credentials=20#4894?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cloudwatch-with-assuming-iam-role.sh | 23 ++-------- .../cloudwatch.sh | 36 +-------------- ...mpose.plaintext.with-assuming-iam-role.yml | 2 +- .../docker-compose.plaintext.yml | 3 ++ ...tch-metrics-sink-with-assuming-iam-role.sh | 36 ++------------- .../cloudwatch-metrics-sink.sh | 36 +-------------- ...mpose.plaintext.with-assuming-iam-role.yml | 2 +- .../docker-compose.plaintext.yml | 3 ++ .../aws-credentials.template | 4 -- .../docker-compose.plaintext.proxy.yml | 2 +- ...mpose.plaintext.with-assuming-iam-role.yml | 2 +- .../docker-compose.plaintext.yml | 2 +- ...modb-sink-with-assuming-iam-role-config.sh | 37 +-------------- .../dynamodb-sink-with-assuming-iam-role.sh | 23 ++-------- ...h-custom-basic-aws-credentials-provider.sh | 46 +------------------ .../dynamodb-sink.sh | 46 +------------------ ...mpose.plaintext.with-assuming-iam-role.yml | 2 +- .../docker-compose.plaintext.yml | 3 ++ ...role-with-custom-awscredentialsprovider.sh | 38 +-------------- .../kinesis-source-proxy.sh | 36 +-------------- .../kinesis-source-with-assuming-iam-role.sh | 23 ++-------- .../kinesis-source.sh | 36 +-------------- ...mpose.plaintext.with-assuming-iam-role.yml | 2 +- .../docker-compose.plaintext.yml | 3 ++ ...ole-with-custom-aws-credential-provider.sh | 37 +-------------- .../lambda-sink-with-assuming-iam-role.sh | 23 ++-------- .../connect-aws-lambda-sink/lambda-sink.sh | 36 +-------------- ...mpose.plaintext.with-assuming-iam-role.yml | 2 +- .../docker-compose.plaintext.yml | 2 + .../redshift-sink-with-assuming-iam-role.sh | 23 ++-------- .../redshift-sink.sh | 36 +-------------- ...kup-and-restore.with-assuming-iam-role.yml | 2 +- ...r-compose.plaintext.backup-and-restore.yml | 3 ++ .../docker-compose.plaintext.generalized.yml | 3 ++ ...ole-with-custom-aws-credential-provider.sh | 38 +-------------- .../s3-source-backup-and-restore-proxy.sh | 36 +-------------- ...d-restore-with-assuming-iam-role-config.sh | 38 +-------------- ...ckup-and-restore-with-assuming-iam-role.sh | 23 ++-------- .../s3-source-backup-and-restore.sh | 36 +-------------- .../s3-source-generalized.sh | 38 +-------------- ...mpose.plaintext.with-assuming-iam-role.yml | 2 +- .../docker-compose.plaintext.yml | 3 ++ ...ole-with-custom-aws-credential-provider.sh | 38 +-------------- .../sqs-source-proxy.sh | 36 +-------------- .../sqs-source-with-assuming-iam-role.sh | 23 ++-------- connect/connect-aws-sqs-source/sqs-source.sh | 36 +-------------- scripts/cli/src/lib/utils_function.sh | 29 +++++++----- 47 files changed, 105 insertions(+), 884 deletions(-) delete mode 100644 connect/connect-aws-dynamodb-sink/aws-credentials.template diff --git a/connect/connect-aws-cloudwatch-logs-source/cloudwatch-with-assuming-iam-role.sh b/connect/connect-aws-cloudwatch-logs-source/cloudwatch-with-assuming-iam-role.sh index 5d88a11f90..9c32bda130 100755 --- a/connect/connect-aws-cloudwatch-logs-source/cloudwatch-with-assuming-iam-role.sh +++ b/connect/connect-aws-cloudwatch-logs-source/cloudwatch-with-assuming-iam-role.sh @@ -4,29 +4,14 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -export AWS_CREDENTIALS_FILE_NAME=credentials-with-assuming-iam-role -if [ ! -f $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME ] +export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role +if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME is not set" + logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi -if [ -z "$AWS_REGION" ] -then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.with-assuming-iam-role.yml" diff --git a/connect/connect-aws-cloudwatch-logs-source/cloudwatch.sh b/connect/connect-aws-cloudwatch-logs-source/cloudwatch.sh index 10fb9ef6be..ce2a064289 100755 --- a/connect/connect-aws-cloudwatch-logs-source/cloudwatch.sh +++ b/connect/connect-aws-cloudwatch-logs-source/cloudwatch.sh @@ -4,41 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" diff --git a/connect/connect-aws-cloudwatch-logs-source/docker-compose.plaintext.with-assuming-iam-role.yml b/connect/connect-aws-cloudwatch-logs-source/docker-compose.plaintext.with-assuming-iam-role.yml index 0a7d3a6234..fcd5e9d7ef 100644 --- a/connect/connect-aws-cloudwatch-logs-source/docker-compose.plaintext.with-assuming-iam-role.yml +++ b/connect/connect-aws-cloudwatch-logs-source/docker-compose.plaintext.with-assuming-iam-role.yml @@ -2,7 +2,7 @@ services: connect: volumes: - - $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-aws-cloudwatch-logs diff --git a/connect/connect-aws-cloudwatch-logs-source/docker-compose.plaintext.yml b/connect/connect-aws-cloudwatch-logs-source/docker-compose.plaintext.yml index f530c558b1..fcd5e9d7ef 100644 --- a/connect/connect-aws-cloudwatch-logs-source/docker-compose.plaintext.yml +++ b/connect/connect-aws-cloudwatch-logs-source/docker-compose.plaintext.yml @@ -1,5 +1,8 @@ --- services: connect: + volumes: + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-aws-cloudwatch-logs diff --git a/connect/connect-aws-cloudwatch-metrics-sink/cloudwatch-metrics-sink-with-assuming-iam-role.sh b/connect/connect-aws-cloudwatch-metrics-sink/cloudwatch-metrics-sink-with-assuming-iam-role.sh index c6be4aac4d..80d1f74f81 100644 --- a/connect/connect-aws-cloudwatch-metrics-sink/cloudwatch-metrics-sink-with-assuming-iam-role.sh +++ b/connect/connect-aws-cloudwatch-metrics-sink/cloudwatch-metrics-sink-with-assuming-iam-role.sh @@ -3,43 +3,15 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -export AWS_CREDENTIALS_FILE_NAME=credentials-with-assuming-iam-role -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) +export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role +if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" + logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi fi -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.with-assuming-iam-role.yml" diff --git a/connect/connect-aws-cloudwatch-metrics-sink/cloudwatch-metrics-sink.sh b/connect/connect-aws-cloudwatch-metrics-sink/cloudwatch-metrics-sink.sh index 4bf8e7e0ae..1411d10edd 100755 --- a/connect/connect-aws-cloudwatch-metrics-sink/cloudwatch-metrics-sink.sh +++ b/connect/connect-aws-cloudwatch-metrics-sink/cloudwatch-metrics-sink.sh @@ -4,41 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" diff --git a/connect/connect-aws-cloudwatch-metrics-sink/docker-compose.plaintext.with-assuming-iam-role.yml b/connect/connect-aws-cloudwatch-metrics-sink/docker-compose.plaintext.with-assuming-iam-role.yml index a7ddbe7da4..a22b44a45e 100644 --- a/connect/connect-aws-cloudwatch-metrics-sink/docker-compose.plaintext.with-assuming-iam-role.yml +++ b/connect/connect-aws-cloudwatch-metrics-sink/docker-compose.plaintext.with-assuming-iam-role.yml @@ -2,7 +2,7 @@ services: connect: volumes: - - $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-aws-cloudwatch-metrics diff --git a/connect/connect-aws-cloudwatch-metrics-sink/docker-compose.plaintext.yml b/connect/connect-aws-cloudwatch-metrics-sink/docker-compose.plaintext.yml index d4697f6a39..a22b44a45e 100644 --- a/connect/connect-aws-cloudwatch-metrics-sink/docker-compose.plaintext.yml +++ b/connect/connect-aws-cloudwatch-metrics-sink/docker-compose.plaintext.yml @@ -1,5 +1,8 @@ --- services: connect: + volumes: + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-aws-cloudwatch-metrics diff --git a/connect/connect-aws-dynamodb-sink/aws-credentials.template b/connect/connect-aws-dynamodb-sink/aws-credentials.template deleted file mode 100644 index 2597003ef0..0000000000 --- a/connect/connect-aws-dynamodb-sink/aws-credentials.template +++ /dev/null @@ -1,4 +0,0 @@ -[default] -aws_access_key_id=:AWS_ACCESS_KEY_ID: -aws_secret_access_key=:AWS_SECRET_ACCESS_KEY: -output=json \ No newline at end of file diff --git a/connect/connect-aws-dynamodb-sink/docker-compose.plaintext.proxy.yml b/connect/connect-aws-dynamodb-sink/docker-compose.plaintext.proxy.yml index 42efa03b10..1435a4282c 100644 --- a/connect/connect-aws-dynamodb-sink/docker-compose.plaintext.proxy.yml +++ b/connect/connect-aws-dynamodb-sink/docker-compose.plaintext.proxy.yml @@ -12,7 +12,7 @@ services: connect: volumes: - - $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-aws-dynamodb diff --git a/connect/connect-aws-dynamodb-sink/docker-compose.plaintext.with-assuming-iam-role.yml b/connect/connect-aws-dynamodb-sink/docker-compose.plaintext.with-assuming-iam-role.yml index 51cd99c110..c8cbe7ed7f 100644 --- a/connect/connect-aws-dynamodb-sink/docker-compose.plaintext.with-assuming-iam-role.yml +++ b/connect/connect-aws-dynamodb-sink/docker-compose.plaintext.with-assuming-iam-role.yml @@ -2,7 +2,7 @@ services: connect: volumes: - - $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-aws-dynamodb \ No newline at end of file diff --git a/connect/connect-aws-dynamodb-sink/docker-compose.plaintext.yml b/connect/connect-aws-dynamodb-sink/docker-compose.plaintext.yml index 51cd99c110..c8cbe7ed7f 100644 --- a/connect/connect-aws-dynamodb-sink/docker-compose.plaintext.yml +++ b/connect/connect-aws-dynamodb-sink/docker-compose.plaintext.yml @@ -2,7 +2,7 @@ services: connect: volumes: - - $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-aws-dynamodb \ No newline at end of file diff --git a/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-assuming-iam-role-config.sh b/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-assuming-iam-role-config.sh index ea5085759d..12efc06f28 100755 --- a/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-assuming-iam-role-config.sh +++ b/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-assuming-iam-role-config.sh @@ -12,36 +12,6 @@ fi AWS_STS_ROLE_ARN=${AWS_STS_ROLE_ARN:-$1} -# this is only used for AWS CLI -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - if [ -z "$AWS_STS_ROLE_ARN" ] then logerror "AWS_STS_ROLE_ARN is not set. Export it as environment variable or pass it as argument" @@ -60,12 +30,7 @@ then exit 1 fi -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials DYNAMODB_TABLE="pg${USER}dynamo${TAG}" DYNAMODB_ENDPOINT="https://dynamodb.$AWS_REGION.amazonaws.com" diff --git a/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-assuming-iam-role.sh b/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-assuming-iam-role.sh index 5391eb92dd..97914ee687 100755 --- a/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-assuming-iam-role.sh +++ b/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-assuming-iam-role.sh @@ -10,29 +10,14 @@ then exit 111 fi -export AWS_CREDENTIALS_FILE_NAME=credentials-with-assuming-iam-role -if [ ! -f $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME ] +export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role +if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME is not set" + logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi -if [ -z "$AWS_REGION" ] -then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials DYNAMODB_TABLE="pg${USER}dynamo${TAG}" DYNAMODB_ENDPOINT="https://dynamodb.$AWS_REGION.amazonaws.com" diff --git a/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-custom-basic-aws-credentials-provider.sh b/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-custom-basic-aws-credentials-provider.sh index 81a29df187..2d07a8278a 100755 --- a/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-custom-basic-aws-credentials-provider.sh +++ b/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-custom-basic-aws-credentials-provider.sh @@ -26,51 +26,7 @@ do set -e done -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -export AWS_CREDENTIALS_FILE_NAME=credentials -if [ ! -f $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME ] -then - log "generating $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME" - mkdir -p $HOME/.aws - sed -e "s|:AWS_ACCESS_KEY_ID:|$AWS_ACCESS_KEY_ID|g" \ - -e "s|:AWS_SECRET_ACCESS_KEY:|$AWS_SECRET_ACCESS_KEY|g" \ - ../../connect/connect-aws-dynamodb-sink/aws-credentials.template > $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials DYNAMODB_TABLE="pg${USER}dynamo${TAG}" DYNAMODB_ENDPOINT="https://dynamodb.$AWS_REGION.amazonaws.com" diff --git a/connect/connect-aws-dynamodb-sink/dynamodb-sink.sh b/connect/connect-aws-dynamodb-sink/dynamodb-sink.sh index eff8afd0d4..e7f0436f2b 100755 --- a/connect/connect-aws-dynamodb-sink/dynamodb-sink.sh +++ b/connect/connect-aws-dynamodb-sink/dynamodb-sink.sh @@ -10,51 +10,7 @@ then exit 111 fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -export AWS_CREDENTIALS_FILE_NAME=credentials -if [ ! -f $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME ] -then - log "generating $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME" - mkdir -p $HOME/.aws - sed -e "s|:AWS_ACCESS_KEY_ID:|$AWS_ACCESS_KEY_ID|g" \ - -e "s|:AWS_SECRET_ACCESS_KEY:|$AWS_SECRET_ACCESS_KEY|g" \ - ../../connect/connect-aws-dynamodb-sink/aws-credentials.template > $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials DYNAMODB_TABLE="pg${USER}dynamo${TAG}" DYNAMODB_ENDPOINT="https://dynamodb.$AWS_REGION.amazonaws.com" diff --git a/connect/connect-aws-kinesis-source/docker-compose.plaintext.with-assuming-iam-role.yml b/connect/connect-aws-kinesis-source/docker-compose.plaintext.with-assuming-iam-role.yml index 4cebd851c9..578a851df2 100644 --- a/connect/connect-aws-kinesis-source/docker-compose.plaintext.with-assuming-iam-role.yml +++ b/connect/connect-aws-kinesis-source/docker-compose.plaintext.with-assuming-iam-role.yml @@ -2,7 +2,7 @@ services: connect: volumes: - - $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-kinesis diff --git a/connect/connect-aws-kinesis-source/docker-compose.plaintext.yml b/connect/connect-aws-kinesis-source/docker-compose.plaintext.yml index 2331095737..c27d3a4ad7 100644 --- a/connect/connect-aws-kinesis-source/docker-compose.plaintext.yml +++ b/connect/connect-aws-kinesis-source/docker-compose.plaintext.yml @@ -1,5 +1,8 @@ --- services: connect: + volumes: + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-kinesis \ No newline at end of file diff --git a/connect/connect-aws-kinesis-source/kinesis-source-assuming-iam-role-with-custom-awscredentialsprovider.sh b/connect/connect-aws-kinesis-source/kinesis-source-assuming-iam-role-with-custom-awscredentialsprovider.sh index e288f4205b..c00d597a2f 100755 --- a/connect/connect-aws-kinesis-source/kinesis-source-assuming-iam-role-with-custom-awscredentialsprovider.sh +++ b/connect/connect-aws-kinesis-source/kinesis-source-assuming-iam-role-with-custom-awscredentialsprovider.sh @@ -32,6 +32,8 @@ then exit 1 fi +handle_aws_credentials + for component in awscredentialsprovider do set +e @@ -46,42 +48,6 @@ do set -e done -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.assuming-iam-role-with-custom-awscredentialsprovider.yml" diff --git a/connect/connect-aws-kinesis-source/kinesis-source-proxy.sh b/connect/connect-aws-kinesis-source/kinesis-source-proxy.sh index 785d9bfd5c..f956e84512 100755 --- a/connect/connect-aws-kinesis-source/kinesis-source-proxy.sh +++ b/connect/connect-aws-kinesis-source/kinesis-source-proxy.sh @@ -10,41 +10,7 @@ then exit 111 fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.nginx-proxy.yml" diff --git a/connect/connect-aws-kinesis-source/kinesis-source-with-assuming-iam-role.sh b/connect/connect-aws-kinesis-source/kinesis-source-with-assuming-iam-role.sh index 2d280ac2a7..c5ca7c85ab 100755 --- a/connect/connect-aws-kinesis-source/kinesis-source-with-assuming-iam-role.sh +++ b/connect/connect-aws-kinesis-source/kinesis-source-with-assuming-iam-role.sh @@ -10,29 +10,14 @@ then exit 111 fi -export AWS_CREDENTIALS_FILE_NAME=credentials-with-assuming-iam-role -if [ ! -f $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME ] +export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role +if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME is not set" + logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi -if [ -z "$AWS_REGION" ] -then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.with-assuming-iam-role.yml" diff --git a/connect/connect-aws-kinesis-source/kinesis-source.sh b/connect/connect-aws-kinesis-source/kinesis-source.sh index 61cc67b668..ae30f4aade 100755 --- a/connect/connect-aws-kinesis-source/kinesis-source.sh +++ b/connect/connect-aws-kinesis-source/kinesis-source.sh @@ -10,41 +10,7 @@ then exit 111 fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" diff --git a/connect/connect-aws-lambda-sink/docker-compose.plaintext.with-assuming-iam-role.yml b/connect/connect-aws-lambda-sink/docker-compose.plaintext.with-assuming-iam-role.yml index 59044c766a..fa124cecda 100644 --- a/connect/connect-aws-lambda-sink/docker-compose.plaintext.with-assuming-iam-role.yml +++ b/connect/connect-aws-lambda-sink/docker-compose.plaintext.with-assuming-iam-role.yml @@ -2,7 +2,7 @@ services: connect: volumes: - - $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-aws-lambda diff --git a/connect/connect-aws-lambda-sink/docker-compose.plaintext.yml b/connect/connect-aws-lambda-sink/docker-compose.plaintext.yml index 753291b1b3..fa124cecda 100644 --- a/connect/connect-aws-lambda-sink/docker-compose.plaintext.yml +++ b/connect/connect-aws-lambda-sink/docker-compose.plaintext.yml @@ -1,5 +1,8 @@ --- services: connect: + volumes: + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-aws-lambda diff --git a/connect/connect-aws-lambda-sink/lambda-sink-assuming-iam-role-with-custom-aws-credential-provider.sh b/connect/connect-aws-lambda-sink/lambda-sink-assuming-iam-role-with-custom-aws-credential-provider.sh index 5c4a461d61..9c834bbc97 100755 --- a/connect/connect-aws-lambda-sink/lambda-sink-assuming-iam-role-with-custom-aws-credential-provider.sh +++ b/connect/connect-aws-lambda-sink/lambda-sink-assuming-iam-role-with-custom-aws-credential-provider.sh @@ -24,35 +24,7 @@ then exit 1 fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - +handle_aws_credentials for component in awscredentialsprovider do @@ -68,13 +40,6 @@ do set -e done -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi - LAMBDA_ROLE_NAME=pg${USER}lambdabrole${TAG} LAMBDA_ROLE_NAME=${LAMBDA_ROLE_NAME//[-._]/} diff --git a/connect/connect-aws-lambda-sink/lambda-sink-with-assuming-iam-role.sh b/connect/connect-aws-lambda-sink/lambda-sink-with-assuming-iam-role.sh index ed4860b233..1f5013d2e2 100755 --- a/connect/connect-aws-lambda-sink/lambda-sink-with-assuming-iam-role.sh +++ b/connect/connect-aws-lambda-sink/lambda-sink-with-assuming-iam-role.sh @@ -4,29 +4,14 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -export AWS_CREDENTIALS_FILE_NAME=credentials-with-assuming-iam-role -if [ ! -f $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME ] +export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role +if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME is not set" + logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi -if [ -z "$AWS_REGION" ] -then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials LAMBDA_ROLE_NAME=pg${USER}lambdabrole${TAG} LAMBDA_ROLE_NAME=${LAMBDA_ROLE_NAME//[-._]/} diff --git a/connect/connect-aws-lambda-sink/lambda-sink.sh b/connect/connect-aws-lambda-sink/lambda-sink.sh index a9fbb931b6..7032576ccb 100755 --- a/connect/connect-aws-lambda-sink/lambda-sink.sh +++ b/connect/connect-aws-lambda-sink/lambda-sink.sh @@ -4,41 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials LAMBDA_ROLE_NAME=pg${USER}lambdabrole${TAG} LAMBDA_ROLE_NAME=${LAMBDA_ROLE_NAME//[-._]/} diff --git a/connect/connect-aws-redshift-sink/docker-compose.plaintext.with-assuming-iam-role.yml b/connect/connect-aws-redshift-sink/docker-compose.plaintext.with-assuming-iam-role.yml index 037c0d5bd2..014a4eb1ca 100644 --- a/connect/connect-aws-redshift-sink/docker-compose.plaintext.with-assuming-iam-role.yml +++ b/connect/connect-aws-redshift-sink/docker-compose.plaintext.with-assuming-iam-role.yml @@ -4,7 +4,7 @@ services: ports: - "5439:5439" volumes: - - $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config - ../../connect/connect-aws-redshift-sink/data:/data environment: diff --git a/connect/connect-aws-redshift-sink/docker-compose.plaintext.yml b/connect/connect-aws-redshift-sink/docker-compose.plaintext.yml index d47b71e6a3..014a4eb1ca 100644 --- a/connect/connect-aws-redshift-sink/docker-compose.plaintext.yml +++ b/connect/connect-aws-redshift-sink/docker-compose.plaintext.yml @@ -4,6 +4,8 @@ services: ports: - "5439:5439" volumes: + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config - ../../connect/connect-aws-redshift-sink/data:/data environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-aws-redshift \ No newline at end of file diff --git a/connect/connect-aws-redshift-sink/redshift-sink-with-assuming-iam-role.sh b/connect/connect-aws-redshift-sink/redshift-sink-with-assuming-iam-role.sh index 2dfdf69f19..225d8a45b6 100755 --- a/connect/connect-aws-redshift-sink/redshift-sink-with-assuming-iam-role.sh +++ b/connect/connect-aws-redshift-sink/redshift-sink-with-assuming-iam-role.sh @@ -4,29 +4,14 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -export AWS_CREDENTIALS_FILE_NAME=credentials-with-assuming-iam-role -if [ ! -f $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME ] +export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role +if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME is not set" + logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi -if [ -z "$AWS_REGION" ] -then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PASSWORD=$(date +%s | cksum | base64 | head -c 32 ; echo) PASSWORD="${PASSWORD}1" diff --git a/connect/connect-aws-redshift-sink/redshift-sink.sh b/connect/connect-aws-redshift-sink/redshift-sink.sh index 9e8e71e403..2d4959fbab 100755 --- a/connect/connect-aws-redshift-sink/redshift-sink.sh +++ b/connect/connect-aws-redshift-sink/redshift-sink.sh @@ -4,41 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PASSWORD=$(date +%s | cksum | base64 | head -c 32 ; echo) PASSWORD="${PASSWORD}1" diff --git a/connect/connect-aws-s3-source/docker-compose.plaintext.backup-and-restore.with-assuming-iam-role.yml b/connect/connect-aws-s3-source/docker-compose.plaintext.backup-and-restore.with-assuming-iam-role.yml index 659144c7d1..1d073e4a36 100644 --- a/connect/connect-aws-s3-source/docker-compose.plaintext.backup-and-restore.with-assuming-iam-role.yml +++ b/connect/connect-aws-s3-source/docker-compose.plaintext.backup-and-restore.with-assuming-iam-role.yml @@ -2,7 +2,7 @@ services: connect: volumes: - - $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-s3-source,/usr/share/confluent-hub-components/confluentinc-kafka-connect-s3 diff --git a/connect/connect-aws-s3-source/docker-compose.plaintext.backup-and-restore.yml b/connect/connect-aws-s3-source/docker-compose.plaintext.backup-and-restore.yml index f3814b6766..8bbb50afa0 100644 --- a/connect/connect-aws-s3-source/docker-compose.plaintext.backup-and-restore.yml +++ b/connect/connect-aws-s3-source/docker-compose.plaintext.backup-and-restore.yml @@ -1,5 +1,8 @@ --- services: connect: + volumes: + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-s3-source,/usr/share/confluent-hub-components/confluentinc-kafka-connect-s3 \ No newline at end of file diff --git a/connect/connect-aws-s3-source/docker-compose.plaintext.generalized.yml b/connect/connect-aws-s3-source/docker-compose.plaintext.generalized.yml index 45fa3220f3..6e595228ab 100644 --- a/connect/connect-aws-s3-source/docker-compose.plaintext.generalized.yml +++ b/connect/connect-aws-s3-source/docker-compose.plaintext.generalized.yml @@ -1,5 +1,8 @@ --- services: connect: + volumes: + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-s3-source \ No newline at end of file diff --git a/connect/connect-aws-s3-source/s3-source-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh b/connect/connect-aws-s3-source/s3-source-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh index 5ca89b6f40..4796634964 100755 --- a/connect/connect-aws-s3-source/s3-source-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh +++ b/connect/connect-aws-s3-source/s3-source-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh @@ -34,6 +34,8 @@ then exit 1 fi +handle_aws_credentials + for component in awscredentialsprovider do set +e @@ -49,42 +51,6 @@ do done -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.yml" diff --git a/connect/connect-aws-s3-source/s3-source-backup-and-restore-proxy.sh b/connect/connect-aws-s3-source/s3-source-backup-and-restore-proxy.sh index 93252864f9..6c391a3c41 100755 --- a/connect/connect-aws-s3-source/s3-source-backup-and-restore-proxy.sh +++ b/connect/connect-aws-s3-source/s3-source-backup-and-restore-proxy.sh @@ -10,41 +10,7 @@ then exit 111 fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.backup-and-restore-proxy.yml" diff --git a/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role-config.sh b/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role-config.sh index eed6547d30..dd9a6c550d 100755 --- a/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role-config.sh +++ b/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role-config.sh @@ -11,36 +11,6 @@ fi AWS_STS_ROLE_ARN=${AWS_STS_ROLE_ARN:-$1} -# this is only used for AWS CLI -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - if [ -z "$AWS_STS_ROLE_ARN" ] then logerror "AWS_STS_ROLE_ARN is not set. Export it as environment variable or pass it as argument" @@ -59,14 +29,8 @@ then exit 1 fi -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials -# credentials file is not mounted in connect container PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.backup-and-restore.with-assuming-iam-role-config.yml" diff --git a/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role.sh b/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role.sh index c05c799030..71cb86ceca 100755 --- a/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role.sh +++ b/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role.sh @@ -10,29 +10,14 @@ then exit 111 fi -export AWS_CREDENTIALS_FILE_NAME=credentials-with-assuming-iam-role -if [ ! -f $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME ] +export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role +if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME is not set" + logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi -if [ -z "$AWS_REGION" ] -then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.backup-and-restore.with-assuming-iam-role.yml" diff --git a/connect/connect-aws-s3-source/s3-source-backup-and-restore.sh b/connect/connect-aws-s3-source/s3-source-backup-and-restore.sh index b589e2c3d0..5d2af06cf7 100755 --- a/connect/connect-aws-s3-source/s3-source-backup-and-restore.sh +++ b/connect/connect-aws-s3-source/s3-source-backup-and-restore.sh @@ -10,41 +10,7 @@ then exit 111 fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.backup-and-restore.yml" diff --git a/connect/connect-aws-s3-source/s3-source-generalized.sh b/connect/connect-aws-s3-source/s3-source-generalized.sh index 5fa20002ea..6937031b76 100755 --- a/connect/connect-aws-s3-source/s3-source-generalized.sh +++ b/connect/connect-aws-s3-source/s3-source-generalized.sh @@ -16,41 +16,7 @@ then exit 111 fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.generalized.yml" @@ -58,8 +24,6 @@ playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker- AWS_BUCKET_NAME=pg-bucket-${USER} AWS_BUCKET_NAME=${AWS_BUCKET_NAME//[-.]/} - - log "Create bucket <$AWS_BUCKET_NAME>, if required" set +e if [ "$AWS_REGION" == "us-east-1" ] diff --git a/connect/connect-aws-sqs-source/docker-compose.plaintext.with-assuming-iam-role.yml b/connect/connect-aws-sqs-source/docker-compose.plaintext.with-assuming-iam-role.yml index 41125504bf..9147318e31 100644 --- a/connect/connect-aws-sqs-source/docker-compose.plaintext.with-assuming-iam-role.yml +++ b/connect/connect-aws-sqs-source/docker-compose.plaintext.with-assuming-iam-role.yml @@ -2,7 +2,7 @@ services: connect: volumes: - - $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-sqs \ No newline at end of file diff --git a/connect/connect-aws-sqs-source/docker-compose.plaintext.yml b/connect/connect-aws-sqs-source/docker-compose.plaintext.yml index 32b7e4c071..9147318e31 100644 --- a/connect/connect-aws-sqs-source/docker-compose.plaintext.yml +++ b/connect/connect-aws-sqs-source/docker-compose.plaintext.yml @@ -1,5 +1,8 @@ --- services: connect: + volumes: + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-sqs \ No newline at end of file diff --git a/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh b/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh index aeb07c6025..708f6361aa 100755 --- a/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh +++ b/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh @@ -36,6 +36,8 @@ then exit 1 fi +handle_aws_credentials + for component in awscredentialsprovider do set +e @@ -50,42 +52,6 @@ do set -e done -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.yml" diff --git a/connect/connect-aws-sqs-source/sqs-source-proxy.sh b/connect/connect-aws-sqs-source/sqs-source-proxy.sh index d922e41239..616fad9d69 100755 --- a/connect/connect-aws-sqs-source/sqs-source-proxy.sh +++ b/connect/connect-aws-sqs-source/sqs-source-proxy.sh @@ -4,41 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.proxy.yml" diff --git a/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh b/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh index fad1e9f17b..dd8c01a081 100755 --- a/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh +++ b/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh @@ -4,29 +4,14 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -export AWS_CREDENTIALS_FILE_NAME=credentials-with-assuming-iam-role -if [ ! -f $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME ] +export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role +if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME is not set" + logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi -if [ -z "$AWS_REGION" ] -then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.with-assuming-iam-role.yml" diff --git a/connect/connect-aws-sqs-source/sqs-source.sh b/connect/connect-aws-sqs-source/sqs-source.sh index 781ed0c006..cf625a36b0 100755 --- a/connect/connect-aws-sqs-source/sqs-source.sh +++ b/connect/connect-aws-sqs-source/sqs-source.sh @@ -4,41 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 75aeb9fa27..1a1c1f7f30 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -4289,12 +4289,21 @@ function maybe_set_azure_subscription () { } function handle_aws_credentials () { - log "handle_aws_credentials" + + tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) + if [ -z "$PG_VERBOSE_MODE" ] + then + trap 'rm -rf $tmp_dir' EXIT + else + log "🐛📂 not deleting tmp dir $tmp_dir" + fi + export AWS_CREDENTIALS_FILE_NAME="$tmp_dir/credentials" + if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ -z $AWS_SESSION_TOKEN ] then if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" + logerror "❌ either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" exit 1 else if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] @@ -4310,12 +4319,18 @@ function handle_aws_credentials () { export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) fi fi + + cat << EOF > $AWS_CREDENTIALS_FILE_NAME + [default] + aws_access_key_id=$AWS_ACCESS_KEY_ID + aws_secret_access_key=$AWS_SECRET_ACCESS_KEY +EOF if [ -z "$AWS_REGION" ] then AWS_REGION=$(aws configure get region | tr '\r' '\n') if [ "$AWS_REGION" == "" ] then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" + logerror "❌ either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" exit 1 fi fi @@ -4330,14 +4345,6 @@ function handle_aws_credentials () { logwarn "the file $HOME/.aws/credentials contains aws_session_token, running example s3-sink-with-short-lived-creds.sh" fi - tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) - if [ -z "$PG_VERBOSE_MODE" ] - then - trap 'rm -rf $tmp_dir' EXIT - else - log "🐛📂 not deleting tmp dir $tmp_dir" - fi - export AWS_CREDENTIALS_FILE_NAME="$tmp_dir/credentials" if [ ! -z $AWS_ACCESS_KEY_ID ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ ! -z "$AWS_SESSION_TOKEN" ] then From 178308c7599fa0199d7dd521653ad8f616686b0c Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 16 Jan 2025 14:37:40 +0100 Subject: [PATCH 163/659] =?UTF-8?q?=F0=9F=91=BE=20AWS=20examples=20are=20n?= =?UTF-8?q?ot=20working=20with=20short-lived=20credentials=20#4894?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ackoverflowerror-with-s3-sink-connector.sh | 36 +------------------ .../docker-compose.redshift.yml | 2 +- .../mqtt-source.sh | 7 ---- .../connect-centralized-license/redshift.sh | 36 +------------------ .../custom-s3-sink.sh | 29 +-------------- .../fully-managed-cloudwatch.sh | 29 +-------------- .../fully-managed-cloudwatch-metrics-sink.sh | 29 +-------------- .../fully-managed-dynamodb-cdc-source.sh | 29 +-------------- .../fully-managed-dynamodb-sink.sh | 29 +-------------- .../fully-managed-kinesis-source.sh | 29 +-------------- .../fully-managed-lambda-sink.sh | 29 +-------------- .../fully-managed-redshift-sink.sh | 29 +-------------- ...nk-confluent-cloud-provider-integration.sh | 31 +--------------- .../fm-aws-s3-sink/fully-managed-s3-sink.sh | 29 +-------------- .../fully-managed-s3-source.sh | 29 +-------------- .../fully-managed-sqs-source.sh | 29 +-------------- connect/connect-filepulse-source/s3-csv.sh | 36 +------------------ connect/connect-filepulse-source/s3-json.sh | 36 +------------------ .../redshift-jdbc-sink.sh | 36 +------------------ .../redshift-jdbc-source.sh | 36 +------------------ scripts/cli/src/lib/utils_function.sh | 14 ++++++-- 21 files changed, 31 insertions(+), 558 deletions(-) diff --git a/academy/connect-connect-aws-s3-sink/s3-sink-repro-000001-stackoverflowerror-with-s3-sink-connector.sh b/academy/connect-connect-aws-s3-sink/s3-sink-repro-000001-stackoverflowerror-with-s3-sink-connector.sh index 6a17a9e405..c5abee4e3b 100755 --- a/academy/connect-connect-aws-s3-sink/s3-sink-repro-000001-stackoverflowerror-with-s3-sink-connector.sh +++ b/academy/connect-connect-aws-s3-sink/s3-sink-repro-000001-stackoverflowerror-with-s3-sink-connector.sh @@ -6,41 +6,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.repro-000001-stackoverflowerror-with-s3-sink-connector.yml" diff --git a/ccloud/connect-centralized-license/docker-compose.redshift.yml b/ccloud/connect-centralized-license/docker-compose.redshift.yml index 67dfca4265..88435eacf8 100644 --- a/ccloud/connect-centralized-license/docker-compose.redshift.yml +++ b/ccloud/connect-centralized-license/docker-compose.redshift.yml @@ -4,7 +4,7 @@ services: ports: - "5439:5439" volumes: - - $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config - ../../ccloud/connect-aws-redshift-sink/redshift-jdbc42-2.1.0.17/redshift-jdbc42-2.1.0.17.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-aws-redshift/lib/redshift-jdbc42-2.1.0.17.jar environment: diff --git a/ccloud/connect-centralized-license/mqtt-source.sh b/ccloud/connect-centralized-license/mqtt-source.sh index d32c7cd34f..e6f012bbbb 100755 --- a/ccloud/connect-centralized-license/mqtt-source.sh +++ b/ccloud/connect-centralized-license/mqtt-source.sh @@ -5,13 +5,6 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi - set +e playground topic delete --topic _confluent-command set -e diff --git a/ccloud/connect-centralized-license/redshift.sh b/ccloud/connect-centralized-license/redshift.sh index ce57989aeb..2242c8f774 100755 --- a/ccloud/connect-centralized-license/redshift.sh +++ b/ccloud/connect-centralized-license/redshift.sh @@ -13,41 +13,7 @@ then cd - fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials playground start-environment --environment ccloud --docker-compose-override-file "${PWD}/docker-compose.redshift.yml" diff --git a/ccloud/custom-connector-connect-aws-s3-sink/custom-s3-sink.sh b/ccloud/custom-connector-connect-aws-s3-sink/custom-s3-sink.sh index f82e0a9da2..6042827a35 100755 --- a/ccloud/custom-connector-connect-aws-s3-sink/custom-s3-sink.sh +++ b/ccloud/custom-connector-connect-aws-s3-sink/custom-s3-sink.sh @@ -74,34 +74,7 @@ then exit 1 fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi +handle_aws_credentials bootstrap_ccloud_environment diff --git a/ccloud/fm-aws-cloudwatch-logs-source/fully-managed-cloudwatch.sh b/ccloud/fm-aws-cloudwatch-logs-source/fully-managed-cloudwatch.sh index 7f76315edd..82f3bafa92 100755 --- a/ccloud/fm-aws-cloudwatch-logs-source/fully-managed-cloudwatch.sh +++ b/ccloud/fm-aws-cloudwatch-logs-source/fully-managed-cloudwatch.sh @@ -4,34 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi +handle_aws_credentials bootstrap_ccloud_environment diff --git a/ccloud/fm-aws-cloudwatch-metrics-sink/fully-managed-cloudwatch-metrics-sink.sh b/ccloud/fm-aws-cloudwatch-metrics-sink/fully-managed-cloudwatch-metrics-sink.sh index 041bf10ca0..e8fdb6ea20 100755 --- a/ccloud/fm-aws-cloudwatch-metrics-sink/fully-managed-cloudwatch-metrics-sink.sh +++ b/ccloud/fm-aws-cloudwatch-metrics-sink/fully-managed-cloudwatch-metrics-sink.sh @@ -4,34 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi +handle_aws_credentials bootstrap_ccloud_environment diff --git a/ccloud/fm-aws-dynamodb-cdc-source/fully-managed-dynamodb-cdc-source.sh b/ccloud/fm-aws-dynamodb-cdc-source/fully-managed-dynamodb-cdc-source.sh index 929b04a749..067745c3d3 100755 --- a/ccloud/fm-aws-dynamodb-cdc-source/fully-managed-dynamodb-cdc-source.sh +++ b/ccloud/fm-aws-dynamodb-cdc-source/fully-managed-dynamodb-cdc-source.sh @@ -10,34 +10,7 @@ then exit 111 fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi +handle_aws_credentials DYNAMODB_TABLE="pg${USER}dynamocdc${TAG}" diff --git a/ccloud/fm-aws-dynamodb-sink/fully-managed-dynamodb-sink.sh b/ccloud/fm-aws-dynamodb-sink/fully-managed-dynamodb-sink.sh index 5d2583fa9c..c6f3f4bd13 100755 --- a/ccloud/fm-aws-dynamodb-sink/fully-managed-dynamodb-sink.sh +++ b/ccloud/fm-aws-dynamodb-sink/fully-managed-dynamodb-sink.sh @@ -10,34 +10,7 @@ then exit 111 fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi +handle_aws_credentials DYNAMODB_TABLE="pg${USER}dynamo${TAG}" diff --git a/ccloud/fm-aws-kinesis-source/fully-managed-kinesis-source.sh b/ccloud/fm-aws-kinesis-source/fully-managed-kinesis-source.sh index b82c56df62..2a92bde322 100755 --- a/ccloud/fm-aws-kinesis-source/fully-managed-kinesis-source.sh +++ b/ccloud/fm-aws-kinesis-source/fully-managed-kinesis-source.sh @@ -4,34 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi +handle_aws_credentials bootstrap_ccloud_environment diff --git a/ccloud/fm-aws-lambda-sink/fully-managed-lambda-sink.sh b/ccloud/fm-aws-lambda-sink/fully-managed-lambda-sink.sh index 327b2e61d7..cdfaa9608b 100755 --- a/ccloud/fm-aws-lambda-sink/fully-managed-lambda-sink.sh +++ b/ccloud/fm-aws-lambda-sink/fully-managed-lambda-sink.sh @@ -4,34 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi +handle_aws_credentials LAMBDA_ROLE_NAME=pg${USER}lambdabrole${TAG} LAMBDA_ROLE_NAME=${LAMBDA_ROLE_NAME//[-._]/} diff --git a/ccloud/fm-aws-redshift-sink/fully-managed-redshift-sink.sh b/ccloud/fm-aws-redshift-sink/fully-managed-redshift-sink.sh index 858c6c1669..7ed942fc02 100755 --- a/ccloud/fm-aws-redshift-sink/fully-managed-redshift-sink.sh +++ b/ccloud/fm-aws-redshift-sink/fully-managed-redshift-sink.sh @@ -4,34 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi +handle_aws_credentials bootstrap_ccloud_environment diff --git a/ccloud/fm-aws-s3-sink/fully-managed-s3-sink-confluent-cloud-provider-integration.sh b/ccloud/fm-aws-s3-sink/fully-managed-s3-sink-confluent-cloud-provider-integration.sh index ec589978c0..06aa2d4863 100755 --- a/ccloud/fm-aws-s3-sink/fully-managed-s3-sink-confluent-cloud-provider-integration.sh +++ b/ccloud/fm-aws-s3-sink/fully-managed-s3-sink-confluent-cloud-provider-integration.sh @@ -13,36 +13,7 @@ then exit 1 fi - - -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi +handle_aws_credentials bootstrap_ccloud_environment diff --git a/ccloud/fm-aws-s3-sink/fully-managed-s3-sink.sh b/ccloud/fm-aws-s3-sink/fully-managed-s3-sink.sh index f2ad731d35..3d342e7077 100755 --- a/ccloud/fm-aws-s3-sink/fully-managed-s3-sink.sh +++ b/ccloud/fm-aws-s3-sink/fully-managed-s3-sink.sh @@ -4,34 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi +handle_aws_credentials bootstrap_ccloud_environment diff --git a/ccloud/fm-aws-s3-source/fully-managed-s3-source.sh b/ccloud/fm-aws-s3-source/fully-managed-s3-source.sh index 815a7d5e81..1e6fc4b096 100755 --- a/ccloud/fm-aws-s3-source/fully-managed-s3-source.sh +++ b/ccloud/fm-aws-s3-source/fully-managed-s3-source.sh @@ -6,34 +6,7 @@ source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi +handle_aws_credentials bootstrap_ccloud_environment diff --git a/ccloud/fm-aws-sqs-source/fully-managed-sqs-source.sh b/ccloud/fm-aws-sqs-source/fully-managed-sqs-source.sh index a5a123a7ac..e41624395b 100755 --- a/ccloud/fm-aws-sqs-source/fully-managed-sqs-source.sh +++ b/ccloud/fm-aws-sqs-source/fully-managed-sqs-source.sh @@ -4,34 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi +handle_aws_credentials bootstrap_ccloud_environment diff --git a/connect/connect-filepulse-source/s3-csv.sh b/connect/connect-filepulse-source/s3-csv.sh index dd299047e6..a3444a6b27 100755 --- a/connect/connect-filepulse-source/s3-csv.sh +++ b/connect/connect-filepulse-source/s3-csv.sh @@ -27,41 +27,7 @@ then fi fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials if ! version_gt $VERSION "1.9.9" then diff --git a/connect/connect-filepulse-source/s3-json.sh b/connect/connect-filepulse-source/s3-json.sh index 6d3865ce2c..002a4a4048 100755 --- a/connect/connect-filepulse-source/s3-json.sh +++ b/connect/connect-filepulse-source/s3-json.sh @@ -27,41 +27,7 @@ then fi fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials if ! version_gt $VERSION "1.9.9" then diff --git a/connect/connect-jdbc-aws-redshift-sink/redshift-jdbc-sink.sh b/connect/connect-jdbc-aws-redshift-sink/redshift-jdbc-sink.sh index 863c41f72a..aec4ac0daa 100755 --- a/connect/connect-jdbc-aws-redshift-sink/redshift-jdbc-sink.sh +++ b/connect/connect-jdbc-aws-redshift-sink/redshift-jdbc-sink.sh @@ -13,41 +13,7 @@ then cd - fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" diff --git a/connect/connect-jdbc-aws-redshift-source/redshift-jdbc-source.sh b/connect/connect-jdbc-aws-redshift-source/redshift-jdbc-source.sh index b379d52656..aa90a883ba 100755 --- a/connect/connect-jdbc-aws-redshift-source/redshift-jdbc-source.sh +++ b/connect/connect-jdbc-aws-redshift-source/redshift-jdbc-source.sh @@ -13,41 +13,7 @@ then cd - fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 1a1c1f7f30..9b2d04cbbc 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -4336,15 +4336,25 @@ EOF fi fi else + # + # AWS short live credentials + # if [ ! -z $AWS_SESSION_TOKEN ] || grep -q "aws_session_token" $HOME/.aws/credentials then if [ ! -z $AWS_SESSION_TOKEN ] then - logwarn "AWS_SESSION_TOKEN environment variable is set, running example s3-sink-with-short-lived-creds.sh" + log "🔏 AWS_SESSION_TOKEN environment variable is set, using AWS short live credentials" else - logwarn "the file $HOME/.aws/credentials contains aws_session_token, running example s3-sink-with-short-lived-creds.sh" + log "🔏 the file $HOME/.aws/credentials contains aws_session_token, using AWS short live credentials" fi + connector_type=$(playground state get run.connector_type) + + if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] + then + logerror "❌ AWS short live credentials are not supported for fully managed connectors or custom connectors" + exit 1 + fi if [ ! -z $AWS_ACCESS_KEY_ID ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ ! -z "$AWS_SESSION_TOKEN" ] then From c0830c18db9ba9981e923a53d90a507d64d29fde Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 16 Jan 2025 15:12:11 +0100 Subject: [PATCH 164/659] fix tag list --- scripts/cli/playground | 56 ++++++++++--------- scripts/cli/src/commands/generate-tag-list.sh | 16 +++--- 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index aa5db92ccc..fdc7120233 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -12400,12 +12400,21 @@ function maybe_set_azure_subscription () { } function handle_aws_credentials () { - log "handle_aws_credentials" + + tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) + if [ -z "$PG_VERBOSE_MODE" ] + then + trap 'rm -rf $tmp_dir' EXIT + else + log "🐛📂 not deleting tmp dir $tmp_dir" + fi + export AWS_CREDENTIALS_FILE_NAME="$tmp_dir/credentials" + if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ -z $AWS_SESSION_TOKEN ] then if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" + logerror "❌ either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" exit 1 else if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] @@ -12422,34 +12431,42 @@ function handle_aws_credentials () { fi fi + + cat << EOF > $AWS_CREDENTIALS_FILE_NAME + [default] + aws_access_key_id=$AWS_ACCESS_KEY_ID + aws_secret_access_key=$AWS_SECRET_ACCESS_KEY +EOF if [ -z "$AWS_REGION" ] then AWS_REGION=$(aws configure get region | tr '\r' '\n') if [ "$AWS_REGION" == "" ] then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" + logerror "❌ either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" exit 1 fi fi fi else + # + # AWS short live credentials + # if [ ! -z $AWS_SESSION_TOKEN ] || grep -q "aws_session_token" $HOME/.aws/credentials then if [ ! -z $AWS_SESSION_TOKEN ] then - logwarn "AWS_SESSION_TOKEN environment variable is set, running example s3-sink-with-short-lived-creds.sh" + log "🔏 AWS_SESSION_TOKEN environment variable is set, using AWS short live credentials" else - logwarn "the file $HOME/.aws/credentials contains aws_session_token, running example s3-sink-with-short-lived-creds.sh" + log "🔏 the file $HOME/.aws/credentials contains aws_session_token, using AWS short live credentials" fi - tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) - if [ -z "$PG_VERBOSE_MODE" ] + connector_type=$(playground state get run.connector_type) + + if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] then - trap 'rm -rf $tmp_dir' EXIT - else - log "🐛📂 not deleting tmp dir $tmp_dir" + logerror "❌ AWS short live credentials are not supported for fully managed connectors or custom connectors" + exit 1 fi - export AWS_CREDENTIALS_FILE_NAME="$tmp_dir/credentials" if [ ! -z $AWS_ACCESS_KEY_ID ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ ! -z "$AWS_SESSION_TOKEN" ] then @@ -12784,24 +12801,13 @@ playground_generate_tag_list_command() { local page=1 local res=$(curl "${base_url}?page_size=${page_size}&page=${page}" 2>/dev/null) - - local tags=$(echo ${res} | jq --raw-output '.results[].name') - - local all_tags="${tags}" - + echo ${res} | jq --raw-output '.results[].name' > /tmp/all_tags local tag_count=$(echo ${res} | jq '.count') - ((page_count=(${tag_count}+${page_size}-1)/${page_size})) # ceil(tag_count / page_size) - for page in $(seq 2 $page_count); do - - tags=$(curl "${base_url}?page_size=${page_size}&page=${page}" 2>/dev/null | jq --raw-output '.results[].name') - - all_tags="${all_tags}${tags}" - + curl "${base_url}?page_size=${page_size}&page=${page}" 2>/dev/null | jq --raw-output '.results[].name' >> /tmp/all_tags done - echo "${all_tags}" | sort - + cat /tmp/all_tags | sort } listAllTags "confluentinc/cp-server-connect-base" | grep -v "ubi8" | grep -v "arm64" | grep -v "amd64" | grep -v "latest" | grep -v "deb8" > $root_folder/scripts/cli/tag-list.txt diff --git a/scripts/cli/src/commands/generate-tag-list.sh b/scripts/cli/src/commands/generate-tag-list.sh index 5781fdf729..6e4146770b 100644 --- a/scripts/cli/src/commands/generate-tag-list.sh +++ b/scripts/cli/src/commands/generate-tag-list.sh @@ -4,16 +4,14 @@ function listAllTags() { [ -z "${repo}" ] && echo "Usage: listTags [page_size]" 1>&2 && return 1 local base_url="https://registry.hub.docker.com/v2/repositories/${repo}/tags" local page=1 - local res=$(curl "${base_url}?page_size=${page_size}&page=${page}" 2>/dev/null) - local tags=$(echo ${res} | jq --raw-output '.results[].name') - local all_tags="${tags}" - local tag_count=$(echo ${res} | jq '.count') - ((page_count=(${tag_count}+${page_size}-1)/${page_size})) # ceil(tag_count / page_size) - for page in $(seq 2 $page_count); do - tags=$(curl "${base_url}?page_size=${page_size}&page=${page}" 2>/dev/null | jq --raw-output '.results[].name') - all_tags="${all_tags}${tags}" + local res=$(curl "${base_url}?page_size=${page_size}&page=${page}" 2>/dev/null) + echo ${res} | jq --raw-output '.results[].name' > /tmp/all_tags + local tag_count=$(echo ${res} | jq '.count') + ((page_count=(${tag_count}+${page_size}-1)/${page_size})) # ceil(tag_count / page_size) + for page in $(seq 2 $page_count); do + curl "${base_url}?page_size=${page_size}&page=${page}" 2>/dev/null | jq --raw-output '.results[].name' >> /tmp/all_tags done - echo "${all_tags}" | sort + cat /tmp/all_tags | sort } listAllTags "confluentinc/cp-server-connect-base" | grep -v "ubi8" | grep -v "arm64" | grep -v "amd64" | grep -v "latest" | grep -v "deb8" > $root_folder/scripts/cli/tag-list.txt \ No newline at end of file From b0284d01900f18d4a06e71020624fbae781bb05b Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 16 Jan 2025 17:58:36 +0100 Subject: [PATCH 165/659] remove ojdbc jar --- .../docker-compose.plaintext.mtls-db-auth.yml | 1 - .../docker-compose.plaintext.mtls.yml | 1 - ...docker-compose.plaintext.no-ojdbc-mtls.yml | 28 ----------------- .../docker-compose.plaintext.no-ojdbc-ssl.yml | 25 --------------- .../docker-compose.plaintext.no-ojdbc.yml | 20 ------------ .../docker-compose.plaintext.ssl.yml | 1 - .../docker-compose.plaintext.yml | 2 -- .../oracle19-sink-mtls-db-auth.sh | 26 ++-------------- .../oracle19-sink-mtls.sh | 26 ++-------------- .../oracle19-sink-ssl.sh | 27 ++-------------- .../oracle19-sink.sh | 22 +------------ .../docker-compose.plaintext.mtls-db-auth.yml | 1 - .../docker-compose.plaintext.mtls.yml | 1 - ...docker-compose.plaintext.no-ojdbc-mtls.yml | 23 -------------- .../docker-compose.plaintext.no-ojdbc-ssl.yml | 22 ------------- .../docker-compose.plaintext.no-ojdbc.yml | 31 ------------------- .../docker-compose.plaintext.ssl.yml | 1 - .../docker-compose.plaintext.yml | 2 -- .../oracle19-mtls-db-auth.sh | 26 ++-------------- .../oracle19-mtls.sh | 26 ++-------------- .../oracle19-ssl.sh | 26 ++-------------- .../connect-jdbc-oracle19-source/oracle19.sh | 21 +------------ 22 files changed, 20 insertions(+), 339 deletions(-) delete mode 100644 connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.no-ojdbc-mtls.yml delete mode 100644 connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.no-ojdbc-ssl.yml delete mode 100644 connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.no-ojdbc.yml delete mode 100644 connect/connect-jdbc-oracle19-source/docker-compose.plaintext.no-ojdbc-mtls.yml delete mode 100644 connect/connect-jdbc-oracle19-source/docker-compose.plaintext.no-ojdbc-ssl.yml delete mode 100644 connect/connect-jdbc-oracle19-source/docker-compose.plaintext.no-ojdbc.yml diff --git a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls-db-auth.yml b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls-db-auth.yml index 74b51388a0..028320f14c 100644 --- a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls-db-auth.yml +++ b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls-db-auth.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle19-sink/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle19-sink/mtls/truststore.jks:/tmp/truststore.jks - ../../connect/connect-jdbc-oracle19-sink/mtls/keystore.jks:/tmp/keystore.jks environment: diff --git a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls.yml b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls.yml index ecdfe03143..652c186f2a 100644 --- a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls.yml +++ b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle19-sink/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle19-sink/mtls/truststore.jks:/tmp/truststore.jks - ../../connect/connect-jdbc-oracle19-sink/mtls/keystore.jks:/tmp/keystore.jks environment: diff --git a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.no-ojdbc-mtls.yml b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.no-ojdbc-mtls.yml deleted file mode 100644 index 2aa4b93fe0..0000000000 --- a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.no-ojdbc-mtls.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -services: - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle19-sink/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - volumes: - - ../../connect/connect-jdbc-oracle19-sink/mtls/truststore.jks:/tmp/truststore.jks - - ../../connect/connect-jdbc-oracle19-sink/mtls/keystore.jks:/tmp/keystore.jks - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - -Djavax.net.ssl.keyStore=/tmp/keystore.jks - -Djavax.net.ssl.keyStorePassword=welcome123 - # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.no-ojdbc-ssl.yml b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.no-ojdbc-ssl.yml deleted file mode 100644 index cdbe136d17..0000000000 --- a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.no-ojdbc-ssl.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -services: - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle19-sink/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - volumes: - - ../../connect/connect-jdbc-oracle19-sink/ssl/truststore.jks:/tmp/truststore.jks - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.no-ojdbc.yml b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.no-ojdbc.yml deleted file mode 100644 index 1014e2223a..0000000000 --- a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.no-ojdbc.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -services: - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle19-sink/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.ssl.yml b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.ssl.yml index c5cb90b7a4..94282009af 100644 --- a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.ssl.yml +++ b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.ssl.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle19-sink/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle19-sink/ssl/truststore.jks:/tmp/truststore.jks environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc diff --git a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.yml b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.yml index b66424be66..1014e2223a 100644 --- a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.yml +++ b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.yml @@ -16,7 +16,5 @@ services: connect: depends_on: - oracle - volumes: - - ../../connect/connect-jdbc-oracle19-sink/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh index 8d202e7f44..f4ea3cd36c 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh @@ -10,29 +10,9 @@ create_or_get_oracle_image "LINUX.X64_193000_db_home.zip" "../../connect/connect # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d oracle -fi +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh index ee514a16ef..154f810d88 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh @@ -10,29 +10,9 @@ create_or_get_oracle_image "LINUX.X64_193000_db_home.zip" "../../connect/connect # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d oracle -fi +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh index 04ac480d0b..bcb3967a9a 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh @@ -10,30 +10,9 @@ create_or_get_oracle_image "LINUX.X64_193000_db_home.zip" "../../connect/connect # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" up -d oracle -fi - +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 log "Oracle DB has started!" diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink.sh index afdec5300a..9f7c04bbd0 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink.sh @@ -6,28 +6,8 @@ source ${DIR}/../../scripts/utils.sh create_or_get_oracle_image "LINUX.X64_193000_db_home.zip" "../../connect/connect-jdbc-oracle19-sink/ora-setup-scripts" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} +PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} -playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.no-ojdbc.yml" -fi - playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 log "Oracle DB has started!" diff --git a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls-db-auth.yml b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls-db-auth.yml index a3abf84639..9911009959 100644 --- a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls-db-auth.yml +++ b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls-db-auth.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle19-source/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle19-source/mtls/truststore.jks:/tmp/truststore.jks - ../../connect/connect-jdbc-oracle19-source/mtls/keystore.jks:/tmp/keystore.jks environment: diff --git a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls.yml b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls.yml index f3f315b05a..ecd31e79e7 100644 --- a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls.yml +++ b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle19-source/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle19-source/mtls/truststore.jks:/tmp/truststore.jks - ../../connect/connect-jdbc-oracle19-source/mtls/keystore.jks:/tmp/keystore.jks environment: diff --git a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.no-ojdbc-mtls.yml b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.no-ojdbc-mtls.yml deleted file mode 100644 index c797c8e764..0000000000 --- a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.no-ojdbc-mtls.yml +++ /dev/null @@ -1,23 +0,0 @@ ---- -services: - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle19-source/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - volumes: - - ../../connect/connect-jdbc-oracle19-source/mtls/truststore.jks:/tmp/truststore.jks - - ../../connect/connect-jdbc-oracle19-source/mtls/keystore.jks:/tmp/keystore.jks - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.no-ojdbc-ssl.yml b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.no-ojdbc-ssl.yml deleted file mode 100644 index 72bbb1aa06..0000000000 --- a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.no-ojdbc-ssl.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -services: - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle19-source/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - volumes: - - ../../connect/connect-jdbc-oracle19-source/ssl/truststore.jks:/tmp/truststore.jks - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.no-ojdbc.yml b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.no-ojdbc.yml deleted file mode 100644 index df5f3d5427..0000000000 --- a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.no-ojdbc.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- -services: - - sql-datagen: - build: - context: ../../connect/connect-jdbc-oracle19-source/oracle-datagen/ - hostname: sql-datagen - container_name: sql-datagen - profiles: - - sql_datagen - volumes: - - ../../connect-jdbc-oracle19-source/oracle-datagen/target/sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar:/sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar - - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle19-source/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.ssl.yml b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.ssl.yml index b2eb25ba00..1fd8f71eca 100644 --- a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.ssl.yml +++ b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.ssl.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle19-source/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle19-source/ssl/truststore.jks:/tmp/truststore.jks environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc diff --git a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.yml b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.yml index f2751913b0..7e527d60f8 100644 --- a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.yml +++ b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.yml @@ -28,7 +28,5 @@ services: connect: depends_on: - oracle - volumes: - - ../../connect/connect-jdbc-oracle19-source/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh b/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh index e5fbb35328..905a96d5d2 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh @@ -10,29 +10,9 @@ create_or_get_oracle_image "LINUX.X64_193000_db_home.zip" "../../connect/connect # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d oracle -fi +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 log "Oracle DB has started!" diff --git a/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh b/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh index b6eb97018c..020e60c716 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh @@ -10,29 +10,9 @@ create_or_get_oracle_image "LINUX.X64_193000_db_home.zip" "../../connect/connect # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d oracle -fi +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 log "Oracle DB has started!" diff --git a/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh b/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh index e08f44a9e6..0ae16c75d9 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh @@ -10,29 +10,9 @@ create_or_get_oracle_image "LINUX.X64_193000_db_home.zip" "../../connect/connect # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" up -d oracle -fi +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 log "Oracle DB has started!" diff --git a/connect/connect-jdbc-oracle19-source/oracle19.sh b/connect/connect-jdbc-oracle19-source/oracle19.sh index 38c5865a5e..9153996487 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19.sh @@ -28,27 +28,8 @@ else log "🛑 SQL_DATAGEN is not set" fi -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} +PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} -playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.no-ojdbc.yml" -fi playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 log "Oracle DB has started!" From e6403359f281b3c9f914a2207357c2624ebd91bb Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 16 Jan 2025 18:01:18 +0100 Subject: [PATCH 166/659] remove ojdbc --- .../docker-compose.plaintext.mtls-db-auth.yml | 1 - .../docker-compose.plaintext.mtls.yml | 1 - ...docker-compose.plaintext.no-ojdbc-mtls.yml | 28 ----------------- .../docker-compose.plaintext.no-ojdbc-ssl.yml | 25 --------------- .../docker-compose.plaintext.no-ojdbc.yml | 20 ------------ .../docker-compose.plaintext.ssl.yml | 1 - .../docker-compose.plaintext.yml | 2 -- .../oracle12-sink-mtls-db-auth.sh | 27 ++-------------- .../oracle12-sink-mtls.sh | 26 ++-------------- .../oracle12-sink-ssl.sh | 26 ++-------------- .../oracle12-sink.sh | 21 +------------ .../docker-compose.plaintext.mtls-db-auth.yml | 1 - .../docker-compose.plaintext.mtls.yml | 1 - ...docker-compose.plaintext.no-ojdbc-mtls.yml | 28 ----------------- .../docker-compose.plaintext.no-ojdbc-ssl.yml | 25 --------------- .../docker-compose.plaintext.no-ojdbc.yml | 31 ------------------- .../docker-compose.plaintext.ssl.yml | 1 - .../docker-compose.plaintext.yml | 2 -- .../oracle12-mtls-db-auth.sh | 26 ++-------------- .../oracle12-mtls.sh | 26 ++-------------- .../oracle12-ssl.sh | 26 ++-------------- .../connect-jdbc-oracle12-source/oracle12.sh | 21 +------------ 22 files changed, 20 insertions(+), 346 deletions(-) delete mode 100644 connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.no-ojdbc-mtls.yml delete mode 100644 connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.no-ojdbc-ssl.yml delete mode 100644 connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.no-ojdbc.yml delete mode 100644 connect/connect-jdbc-oracle12-source/docker-compose.plaintext.no-ojdbc-mtls.yml delete mode 100644 connect/connect-jdbc-oracle12-source/docker-compose.plaintext.no-ojdbc-ssl.yml delete mode 100644 connect/connect-jdbc-oracle12-source/docker-compose.plaintext.no-ojdbc.yml diff --git a/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.mtls-db-auth.yml b/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.mtls-db-auth.yml index df11179225..ddc673fdfc 100644 --- a/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.mtls-db-auth.yml +++ b/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.mtls-db-auth.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle12-sink/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle12-sink/mtls/truststore.jks:/tmp/truststore.jks - ../../connect/connect-jdbc-oracle12-sink/mtls/keystore.jks:/tmp/keystore.jks environment: diff --git a/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.mtls.yml b/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.mtls.yml index b7df44b8c1..f790d4b47d 100644 --- a/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.mtls.yml +++ b/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.mtls.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle12-sink/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle12-sink/mtls/truststore.jks:/tmp/truststore.jks - ../../connect/connect-jdbc-oracle12-sink/mtls/keystore.jks:/tmp/keystore.jks environment: diff --git a/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.no-ojdbc-mtls.yml b/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.no-ojdbc-mtls.yml deleted file mode 100644 index 10294ce6cc..0000000000 --- a/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.no-ojdbc-mtls.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -services: - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle12-sink/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - volumes: - - ../../connect/connect-jdbc-oracle12-sink/mtls/truststore.jks:/tmp/truststore.jks - - ../../connect/connect-jdbc-oracle12-sink/mtls/keystore.jks:/tmp/keystore.jks - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - -Djavax.net.ssl.keyStore=/tmp/keystore.jks - -Djavax.net.ssl.keyStorePassword=welcome123 - # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.no-ojdbc-ssl.yml b/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.no-ojdbc-ssl.yml deleted file mode 100644 index e0ff095bf4..0000000000 --- a/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.no-ojdbc-ssl.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -services: - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle12-sink/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - volumes: - - ../../connect/connect-jdbc-oracle12-sink/ssl/truststore.jks:/tmp/truststore.jks - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.no-ojdbc.yml b/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.no-ojdbc.yml deleted file mode 100644 index eb001dd4b9..0000000000 --- a/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.no-ojdbc.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -services: - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle12-sink/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.ssl.yml b/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.ssl.yml index a755e7cbe6..83e0c1b83f 100644 --- a/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.ssl.yml +++ b/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.ssl.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle12-sink/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle12-sink/ssl/truststore.jks:/tmp/truststore.jks environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc diff --git a/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.yml b/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.yml index bbc277d9e3..eb001dd4b9 100644 --- a/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.yml +++ b/connect/connect-jdbc-oracle12-sink/docker-compose.plaintext.yml @@ -16,7 +16,5 @@ services: connect: depends_on: - oracle - volumes: - - ../../connect/connect-jdbc-oracle12-sink/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh index d497f20df4..369b28953d 100755 --- a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh @@ -10,30 +10,9 @@ create_or_get_oracle_image "linuxx64_12201_database.zip" "../../connect/connect- # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d oracle -fi - +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 900 log "Oracle DB has started!" diff --git a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh index b064da58c6..eb21e56452 100755 --- a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh +++ b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh @@ -10,29 +10,9 @@ create_or_get_oracle_image "linuxx64_12201_database.zip" "../../connect/connect- # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d oracle -fi +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 900 diff --git a/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh b/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh index 0ebb5037ca..80632b47c9 100755 --- a/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh +++ b/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh @@ -10,29 +10,9 @@ create_or_get_oracle_image "linuxx64_12201_database.zip" "../../connect/connect- # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" up -d oracle -fi +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 900 diff --git a/connect/connect-jdbc-oracle12-sink/oracle12-sink.sh b/connect/connect-jdbc-oracle12-sink/oracle12-sink.sh index 67a5381c9c..9dae3181f5 100755 --- a/connect/connect-jdbc-oracle12-sink/oracle12-sink.sh +++ b/connect/connect-jdbc-oracle12-sink/oracle12-sink.sh @@ -6,27 +6,8 @@ source ${DIR}/../../scripts/utils.sh create_or_get_oracle_image "linuxx64_12201_database.zip" "../../connect/connect-jdbc-oracle12-sink/ora-setup-scripts" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} +PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} -playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.no-ojdbc.yml" -fi playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 900 log "Oracle DB has started!" diff --git a/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.mtls-db-auth.yml b/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.mtls-db-auth.yml index ce7420d7df..066d59d91a 100644 --- a/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.mtls-db-auth.yml +++ b/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.mtls-db-auth.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle12-source/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle12-source/mtls/truststore.jks:/tmp/truststore.jks - ../../connect/connect-jdbc-oracle12-source/mtls/keystore.jks:/tmp/keystore.jks environment: diff --git a/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.mtls.yml b/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.mtls.yml index 04ed5306cb..9e69e3e917 100644 --- a/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.mtls.yml +++ b/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.mtls.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle12-source/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle12-source/mtls/truststore.jks:/tmp/truststore.jks - ../../connect/connect-jdbc-oracle12-source/mtls/keystore.jks:/tmp/keystore.jks environment: diff --git a/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.no-ojdbc-mtls.yml b/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.no-ojdbc-mtls.yml deleted file mode 100644 index 62353dbf4a..0000000000 --- a/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.no-ojdbc-mtls.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -services: - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle12-source/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - volumes: - - ../../connect/connect-jdbc-oracle12-source/mtls/truststore.jks:/tmp/truststore.jks - - ../../connect/connect-jdbc-oracle12-source/mtls/keystore.jks:/tmp/keystore.jks - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - -Djavax.net.ssl.keyStore=/tmp/keystore.jks - -Djavax.net.ssl.keyStorePassword=welcome123 - # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.no-ojdbc-ssl.yml b/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.no-ojdbc-ssl.yml deleted file mode 100644 index 0bc978c8ee..0000000000 --- a/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.no-ojdbc-ssl.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -services: - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle12-source/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - volumes: - - ../../connect/connect-jdbc-oracle12-source/ssl/truststore.jks:/tmp/truststore.jks - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.no-ojdbc.yml b/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.no-ojdbc.yml deleted file mode 100644 index 7548817f4f..0000000000 --- a/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.no-ojdbc.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- -services: - - sql-datagen: - build: - context: ../../connect/connect-jdbc-oracle12-source/oracle-datagen/ - hostname: sql-datagen - container_name: sql-datagen - profiles: - - sql_datagen - volumes: - - ../../connect-jdbc-oracle12-source/oracle-datagen/target/sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar:/sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar - - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle12-source/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.ssl.yml b/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.ssl.yml index 043c273f31..300376c82a 100644 --- a/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.ssl.yml +++ b/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.ssl.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle12-source/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle12-source/ssl/truststore.jks:/tmp/truststore.jks environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc diff --git a/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.yml b/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.yml index 0f3fbad62b..7548817f4f 100644 --- a/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.yml +++ b/connect/connect-jdbc-oracle12-source/docker-compose.plaintext.yml @@ -27,7 +27,5 @@ services: connect: depends_on: - oracle - volumes: - - ../../connect/connect-jdbc-oracle12-source/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh b/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh index c565c754eb..b96b43b6ca 100755 --- a/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh @@ -10,29 +10,9 @@ create_or_get_oracle_image "linuxx64_12201_database.zip" "../../connect/connect- # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth-db-auth.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth-db-auth.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d oracle -fi +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth-db-auth.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth-db-auth.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 900 log "Oracle DB has started!" diff --git a/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh b/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh index 20c7ad5de8..a5f22a969b 100755 --- a/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh +++ b/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh @@ -10,29 +10,9 @@ create_or_get_oracle_image "linuxx64_12201_database.zip" "../../connect/connect- # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d oracle -fi +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 900 log "Oracle DB has started!" diff --git a/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh b/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh index ddae6af9e9..3dd4891e55 100755 --- a/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh +++ b/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh @@ -10,29 +10,9 @@ create_or_get_oracle_image "linuxx64_12201_database.zip" "../../connect/connect- # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" up -d oracle -fi +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 900 log "Oracle DB has started!" diff --git a/connect/connect-jdbc-oracle12-source/oracle12.sh b/connect/connect-jdbc-oracle12-source/oracle12.sh index 5352065831..df0e9e3d6d 100755 --- a/connect/connect-jdbc-oracle12-source/oracle12.sh +++ b/connect/connect-jdbc-oracle12-source/oracle12.sh @@ -28,27 +28,8 @@ else log "🛑 SQL_DATAGEN is not set" fi -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} +PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} -playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.no-ojdbc.yml" -fi playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 900 log "Oracle DB has started!" From d31617c5283e772b83e656236b3f4c6fb1c9ead7 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 16 Jan 2025 18:12:14 +0100 Subject: [PATCH 167/659] remove ojdbc jar --- ccloud/fm-jdbc-oracle19-sink/README.md | 2 +- connect/connect-jdbc-oracle11-sink/README.md | 2 +- .../docker-compose.plaintext.no-ojdbc.yml | 20 --------- .../docker-compose.plaintext.yml | 2 - .../oracle11-sink.sh | 16 +------ .../connect-jdbc-oracle11-source/README.md | 2 +- .../docker-compose.plaintext.no-ojdbc.yml | 30 ------------- .../docker-compose.plaintext.yml | 2 - .../connect-jdbc-oracle11-source/oracle11.sh | 21 +-------- connect/connect-jdbc-oracle12-sink/README.md | 2 +- .../oracle12-sink-mtls-db-auth.sh | 16 ++----- .../oracle12-sink-mtls.sh | 17 ++------ .../oracle12-sink-ssl.sh | 8 ---- .../connect-jdbc-oracle12-source/README.md | 2 +- .../oracle12-mtls-db-auth.sh | 16 ++----- .../oracle12-mtls.sh | 16 ++----- .../oracle12-ssl.sh | 16 ++----- connect/connect-jdbc-oracle19-sink/README.md | 2 +- .../oracle19-sink-mtls-db-auth.sh | 16 ++----- .../oracle19-sink-mtls.sh | 16 ++----- .../oracle19-sink-ssl.sh | 16 ++----- .../connect-jdbc-oracle19-source/README.md | 2 +- .../oracle19-mtls-db-auth.sh | 16 ++----- .../oracle19-mtls.sh | 16 ++----- .../oracle19-ssl.sh | 16 ++----- connect/connect-jdbc-oracle21-sink/README.md | 2 +- .../docker-compose.plaintext.mtls-db-auth.yml | 1 - .../docker-compose.plaintext.mtls.yml | 1 - ...docker-compose.plaintext.no-ojdbc-mtls.yml | 28 ------------ .../docker-compose.plaintext.no-ojdbc-ssl.yml | 25 ----------- .../docker-compose.plaintext.no-ojdbc.yml | 20 --------- .../docker-compose.plaintext.ssl.yml | 1 - .../docker-compose.plaintext.yml | 2 - .../oracle21-sink-mtls-db-auth.sh | 43 +++---------------- .../oracle21-sink-mtls.sh | 43 +++---------------- .../oracle21-sink-ssl.sh | 43 +++---------------- .../oracle21-sink.sh | 21 +-------- .../connect-jdbc-oracle21-source/README.md | 2 +- .../docker-compose.plaintext.mtls-db-auth.yml | 1 - .../docker-compose.plaintext.mtls.yml | 1 - ...docker-compose.plaintext.no-ojdbc-mtls.yml | 28 ------------ .../docker-compose.plaintext.no-ojdbc-ssl.yml | 25 ----------- .../docker-compose.plaintext.no-ojdbc.yml | 31 ------------- .../docker-compose.plaintext.ssl.yml | 1 - .../docker-compose.plaintext.yml | 2 - .../oracle21-mtls-db-auth.sh | 42 +++--------------- .../oracle21-mtls.sh | 42 +++--------------- .../oracle21-ssl.sh | 42 +++--------------- .../connect-jdbc-oracle21-source/oracle21.sh | 21 +-------- 49 files changed, 99 insertions(+), 659 deletions(-) delete mode 100644 connect/connect-jdbc-oracle11-sink/docker-compose.plaintext.no-ojdbc.yml delete mode 100644 connect/connect-jdbc-oracle11-source/docker-compose.plaintext.no-ojdbc.yml delete mode 100644 connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.no-ojdbc-mtls.yml delete mode 100644 connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.no-ojdbc-ssl.yml delete mode 100644 connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.no-ojdbc.yml delete mode 100644 connect/connect-jdbc-oracle21-source/docker-compose.plaintext.no-ojdbc-mtls.yml delete mode 100644 connect/connect-jdbc-oracle21-source/docker-compose.plaintext.no-ojdbc-ssl.yml delete mode 100644 connect/connect-jdbc-oracle21-source/docker-compose.plaintext.no-ojdbc.yml diff --git a/ccloud/fm-jdbc-oracle19-sink/README.md b/ccloud/fm-jdbc-oracle19-sink/README.md index 347147d13b..d680ab61c8 100644 --- a/ccloud/fm-jdbc-oracle19-sink/README.md +++ b/ccloud/fm-jdbc-oracle19-sink/README.md @@ -8,7 +8,7 @@ Quickly test [Fully Managed JDBC Source](https://docs.confluent.io/cloud/current N.B: if you're a Confluent employee, please check this [link](https://confluent.slack.com/archives/C0116NM415F/p1636391410032900) and also [here](https://confluent.slack.com/archives/C0116NM415F/p1636389483030900). -* If you're using a JDBC connector version before `10.0.0`, you need to download Oracle Database 12.2.0.1 JDBC Driver `ojdbc8.jar`from this [page](https://www.oracle.com/database/technologies/jdbc-ucp-122-downloads.html) and place it in `./ojdbc8.jar` + Download Oracle Database 19c (19.3) for Linux x86-64 `LINUX.X64_193000_db_home.zip`from this [page](https://www.oracle.com/database/technologies/oracle19c-linux-downloads.html) and place it in `./LINUX.X64_193000_db_home.zip` diff --git a/connect/connect-jdbc-oracle11-sink/README.md b/connect/connect-jdbc-oracle11-sink/README.md index d348d04c17..8b1656a84c 100644 --- a/connect/connect-jdbc-oracle11-sink/README.md +++ b/connect/connect-jdbc-oracle11-sink/README.md @@ -7,7 +7,7 @@ Quickly test [JDBC Sink](https://docs.confluent.io/current/connect/kafka-connect-jdbc/sink-connector/index.html#quick-start) connector with Oracle 11. -* If you're using a JDBC connector version before `10.0.0`, you need to download Oracle Database 11g Release 2 (11.2.0.4) JDBC driver `ojdbc6.jar`from this [page](https://www.oracle.com/database/technologies/jdbcdriver-ucp-downloads.html) and place it in `./ojdbc6.jar` + N.B: if you're a Confluent employee, please check this [link](https://confluent.slack.com/archives/C0116NM415F/p1636391410032900). diff --git a/connect/connect-jdbc-oracle11-sink/docker-compose.plaintext.no-ojdbc.yml b/connect/connect-jdbc-oracle11-sink/docker-compose.plaintext.no-ojdbc.yml deleted file mode 100644 index b27b948996..0000000000 --- a/connect/connect-jdbc-oracle11-sink/docker-compose.plaintext.no-ojdbc.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -services: - oracle: - # https://github.com/wnameless/docker-oracle-xe-11g - image: wnameless/oracle-xe-11g-r2 - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle11-sink/00-oracle-init.sql:/docker-entrypoint-initdb.d/00-oracle-init.sql - - ../../connect/connect-jdbc-oracle11-sink/01-create-table.sh:/docker-entrypoint-initdb.d/01-create-table.sh - environment: - ORACLE_ALLOW_REMOTE: "true" - - connect: - depends_on: - - oracle - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle11-sink/docker-compose.plaintext.yml b/connect/connect-jdbc-oracle11-sink/docker-compose.plaintext.yml index 9ce41f79eb..b27b948996 100644 --- a/connect/connect-jdbc-oracle11-sink/docker-compose.plaintext.yml +++ b/connect/connect-jdbc-oracle11-sink/docker-compose.plaintext.yml @@ -16,7 +16,5 @@ services: connect: depends_on: - oracle - volumes: - - ../../connect/connect-jdbc-oracle11-sink/ojdbc6.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc6.jar environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle11-sink/oracle11-sink.sh b/connect/connect-jdbc-oracle11-sink/oracle11-sink.sh index 69e3de7c7c..07eeb76a5b 100755 --- a/connect/connect-jdbc-oracle11-sink/oracle11-sink.sh +++ b/connect/connect-jdbc-oracle11-sink/oracle11-sink.sh @@ -4,22 +4,8 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc6.jar" - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} +PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} -playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.no-ojdbc.yml" -fi log "Creating JDBC Oracle sink connector" playground connector create-or-update --connector oracle-sink << EOF diff --git a/connect/connect-jdbc-oracle11-source/README.md b/connect/connect-jdbc-oracle11-source/README.md index 3668e4d6f3..323941ff98 100644 --- a/connect/connect-jdbc-oracle11-source/README.md +++ b/connect/connect-jdbc-oracle11-source/README.md @@ -6,7 +6,7 @@ Quickly test [JDBC Source](https://docs.confluent.io/current/connect/kafka-connect-jdbc/source-connector/index.html#kconnect-long-jdbc-source-connector) connector with Oracle 11. -* If you're using a JDBC connector version before `10.0.0`, you need to download Oracle Database 11g Release 2 (11.2.0.4) JDBC driver `ojdbc6.jar`from this [page](https://www.oracle.com/database/technologies/jdbcdriver-ucp-downloads.html) and place it in `./ojdbc6.jar` + N.B: if you're a Confluent employee, please check this [link](https://confluent.slack.com/archives/C0116NM415F/p1636391410032900). diff --git a/connect/connect-jdbc-oracle11-source/docker-compose.plaintext.no-ojdbc.yml b/connect/connect-jdbc-oracle11-source/docker-compose.plaintext.no-ojdbc.yml deleted file mode 100644 index 6b5bd6eb86..0000000000 --- a/connect/connect-jdbc-oracle11-source/docker-compose.plaintext.no-ojdbc.yml +++ /dev/null @@ -1,30 +0,0 @@ ---- -services: - - sql-datagen: - build: - context: ../../connect/connect-jdbc-oracle11-source/oracle-datagen/ - hostname: sql-datagen - container_name: sql-datagen - profiles: - - sql_datagen - volumes: - - ../../connect-jdbc-oracle11-source/oracle-datagen/target/sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar:/sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar - - oracle: - # https://github.com/wnameless/docker-oracle-xe-11g - image: wnameless/oracle-xe-11g-r2 - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle11-source/00-oracle-init.sql:/docker-entrypoint-initdb.d/00-oracle-init.sql - environment: - ORACLE_ALLOW_REMOTE: "true" - - connect: - depends_on: - - oracle - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle11-source/docker-compose.plaintext.yml b/connect/connect-jdbc-oracle11-source/docker-compose.plaintext.yml index 02779cdc1b..6b5bd6eb86 100644 --- a/connect/connect-jdbc-oracle11-source/docker-compose.plaintext.yml +++ b/connect/connect-jdbc-oracle11-source/docker-compose.plaintext.yml @@ -26,7 +26,5 @@ services: connect: depends_on: - oracle - volumes: - - ../../connect/connect-jdbc-oracle11-source/ojdbc6.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc6.jar environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle11-source/oracle11.sh b/connect/connect-jdbc-oracle11-source/oracle11.sh index 61e6b9da3b..db6795493d 100755 --- a/connect/connect-jdbc-oracle11-source/oracle11.sh +++ b/connect/connect-jdbc-oracle11-source/oracle11.sh @@ -26,27 +26,8 @@ else log "🛑 SQL_DATAGEN is not set" fi -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc6.jar" - if [ ! -f ${DIR}/ojdbc6.jar ] - then - logerror "ERROR: ${DIR}/ojdbc6.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} +PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} -playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.no-ojdbc.yml" -fi log "create table" docker exec -i oracle bash -c "ORACLE_SID=XE;export ORACLE_SID;export ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe;/u01/app/oracle/product/11.2.0/xe/bin/sqlplus myuser/mypassword@//localhost:1521/XE" << EOF diff --git a/connect/connect-jdbc-oracle12-sink/README.md b/connect/connect-jdbc-oracle12-sink/README.md index 33419692c8..101ab94466 100644 --- a/connect/connect-jdbc-oracle12-sink/README.md +++ b/connect/connect-jdbc-oracle12-sink/README.md @@ -8,7 +8,7 @@ Quickly test [JDBC Sink](https://docs.confluent.io/current/connect/kafka-connect N.B: if you're a Confluent employee, please check this [link](https://confluent.slack.com/archives/C0116NM415F/p1636391410032900) and also [here](https://confluent.slack.com/archives/C0116NM415F/p1636389483030900). -* If you're using a JDBC connector version before `10.0.0`, you need to download Oracle Database 12.2.0.1 JDBC Driver `ojdbc8.jar`from this [page](https://www.oracle.com/database/technologies/jdbc-ucp-122-downloads.html) and place it in `./ojdbc8.jar` + Note: Oracle Database Enterprise Edition 12.x and 18c are no longer available for download. The software is available as a media or FTP request for those customers who own a valid Oracle Database product license for any edition. To request access to these releases, follow the instructions in [Oracle Support Document 1071023.1 (Requesting Physical Shipment or Download URL for Software Media)](https://support.oracle.com/epmos/faces/ui/km/DocumentDisplay.jspx?id=1071023.1) from My Oracle Support. diff --git a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh index 369b28953d..de335312f0 100755 --- a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh @@ -137,19 +137,11 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d --quiet-pull +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh index eb21e56452..6cc7e825c2 100755 --- a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh +++ b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh @@ -132,21 +132,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi - +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready sleep 10 diff --git a/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh b/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh index 80632b47c9..e6bf213572 100755 --- a/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh +++ b/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh @@ -104,20 +104,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d --quiet-pull command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi wait_container_ready diff --git a/connect/connect-jdbc-oracle12-source/README.md b/connect/connect-jdbc-oracle12-source/README.md index f939ee796b..ddadf0f0c1 100644 --- a/connect/connect-jdbc-oracle12-source/README.md +++ b/connect/connect-jdbc-oracle12-source/README.md @@ -8,7 +8,7 @@ Quickly test [JDBC Source](https://docs.confluent.io/current/connect/kafka-conne N.B: if you're a Confluent employee, please check this [link](https://confluent.slack.com/archives/C0116NM415F/p1636391410032900) and also [here](https://confluent.slack.com/archives/C0116NM415F/p1636389483030900). -* If you're using a JDBC connector version before `10.0.0`, you need to download Oracle Database 12.2.0.1 JDBC Driver `ojdbc8.jar`from this [page](https://www.oracle.com/database/technologies/jdbc-ucp-122-downloads.html) and place it in `./ojdbc8.jar` + Note: Oracle Database Enterprise Edition 12.x and 18c are no longer available for download. The software is available as a media or FTP request for those customers who own a valid Oracle Database product license for any edition. To request access to these releases, follow the instructions in [Oracle Support Document 1071023.1 (Requesting Physical Shipment or Download URL for Software Media)](https://support.oracle.com/epmos/faces/ui/km/DocumentDisplay.jspx?id=1071023.1) from My Oracle Support. diff --git a/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh b/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh index b96b43b6ca..22f7a3559b 100755 --- a/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh @@ -171,20 +171,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh b/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh index a5f22a969b..8434c4b541 100755 --- a/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh +++ b/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh @@ -165,20 +165,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh b/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh index 3dd4891e55..bb0c148f18 100755 --- a/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh +++ b/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh @@ -137,20 +137,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle19-sink/README.md b/connect/connect-jdbc-oracle19-sink/README.md index c94c0d1aff..4c79b19691 100644 --- a/connect/connect-jdbc-oracle19-sink/README.md +++ b/connect/connect-jdbc-oracle19-sink/README.md @@ -8,7 +8,7 @@ Quickly test [JDBC Source](https://docs.confluent.io/current/connect/kafka-conne N.B: if you're a Confluent employee, please check this [link](https://confluent.slack.com/archives/C0116NM415F/p1636391410032900) and also [here](https://confluent.slack.com/archives/C0116NM415F/p1636389483030900). -* If you're using a JDBC connector version before `10.0.0`, you need to download Oracle Database 12.2.0.1 JDBC Driver `ojdbc8.jar`from this [page](https://www.oracle.com/database/technologies/jdbc-ucp-122-downloads.html) and place it in `./ojdbc8.jar` + Download Oracle Database 19c (19.3) for Linux x86-64 `LINUX.X64_193000_db_home.zip`from this [page](https://www.oracle.com/database/technologies/oracle19c-linux-downloads.html) and place it in `./LINUX.X64_193000_db_home.zip` diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh index f4ea3cd36c..b31887fcbf 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh @@ -138,19 +138,11 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d --quiet-pull +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh index 154f810d88..0fac4e3aa7 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh @@ -132,20 +132,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh index bcb3967a9a..e9a44b7211 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh @@ -103,20 +103,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle19-source/README.md b/connect/connect-jdbc-oracle19-source/README.md index a5a01d1593..21ff867de9 100644 --- a/connect/connect-jdbc-oracle19-source/README.md +++ b/connect/connect-jdbc-oracle19-source/README.md @@ -6,7 +6,7 @@ Quickly test [JDBC Source](https://docs.confluent.io/current/connect/kafka-conne N.B: if you're a Confluent employee, please check this [link](https://confluent.slack.com/archives/C0116NM415F/p1636391410032900) and also [here](https://confluent.slack.com/archives/C0116NM415F/p1636389483030900). -* If you're using a JDBC connector version before `10.0.0`, you need to download Oracle Database 12.2.0.1 JDBC Driver `ojdbc8.jar`from this [page](https://www.oracle.com/database/technologies/jdbc-ucp-122-downloads.html) and place it in `./ojdbc8.jar` + Download Oracle Database 19c (19.3) for Linux x86-64 `LINUX.X64_193000_db_home.zip`from this [page](https://www.oracle.com/database/technologies/oracle19c-linux-downloads.html) and place it in `./LINUX.X64_193000_db_home.zip` diff --git a/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh b/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh index 905a96d5d2..3b8b3ed3b1 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh @@ -171,20 +171,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh b/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh index 020e60c716..785bf3b133 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh @@ -165,20 +165,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh b/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh index 0ae16c75d9..3071228e1f 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh @@ -137,20 +137,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle21-sink/README.md b/connect/connect-jdbc-oracle21-sink/README.md index 3337a24f9b..e0b17419b1 100644 --- a/connect/connect-jdbc-oracle21-sink/README.md +++ b/connect/connect-jdbc-oracle21-sink/README.md @@ -8,7 +8,7 @@ Quickly test [JDBC Source](https://docs.confluent.io/current/connect/kafka-conne N.B: if you're a Confluent employee, please check this [link](https://confluent.slack.com/archives/C0116NM415F/p1636391410032900) and also [here](https://confluent.slack.com/archives/C0116NM415F/p1636389483030900). -* If you're using a JDBC connector version before `10.0.0`, you need to download Oracle Database 12.2.0.1 JDBC Driver `ojdbc8.jar`from this [page](https://www.oracle.com/database/technologies/jdbc-ucp-122-downloads.html) and place it in `./ojdbc8.jar` + Download Oracle Database 21c (21.3) for Linux x86-64 `LINUX.X64_213000_db_home.zip`from this [page](https://www.oracle.com/database/technologies/oracle21c-linux-downloads.html) and place it in `./LINUX.X64_213000_db_home.zip` diff --git a/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.mtls-db-auth.yml b/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.mtls-db-auth.yml index ce06c6f237..2779bf9706 100644 --- a/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.mtls-db-auth.yml +++ b/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.mtls-db-auth.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle21-sink/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle21-sink/mtls/truststore.jks:/tmp/truststore.jks - ../../connect/connect-jdbc-oracle21-sink/mtls/keystore.jks:/tmp/keystore.jks environment: diff --git a/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.mtls.yml b/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.mtls.yml index d082c84103..45d2f3609a 100644 --- a/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.mtls.yml +++ b/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.mtls.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle21-sink/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle21-sink/mtls/truststore.jks:/tmp/truststore.jks - ../../connect/connect-jdbc-oracle21-sink/mtls/keystore.jks:/tmp/keystore.jks environment: diff --git a/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.no-ojdbc-mtls.yml b/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.no-ojdbc-mtls.yml deleted file mode 100644 index 0f4238b3f9..0000000000 --- a/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.no-ojdbc-mtls.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -services: - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle21-sink/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - volumes: - - ../../connect/connect-jdbc-oracle21-sink/mtls/truststore.jks:/tmp/truststore.jks - - ../../connect/connect-jdbc-oracle21-sink/mtls/keystore.jks:/tmp/keystore.jks - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - -Djavax.net.ssl.keyStore=/tmp/keystore.jks - -Djavax.net.ssl.keyStorePassword=welcome123 - # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.no-ojdbc-ssl.yml b/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.no-ojdbc-ssl.yml deleted file mode 100644 index efabff6946..0000000000 --- a/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.no-ojdbc-ssl.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -services: - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle21-sink/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - volumes: - - ../../connect/connect-jdbc-oracle21-sink/ssl/truststore.jks:/tmp/truststore.jks - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.no-ojdbc.yml b/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.no-ojdbc.yml deleted file mode 100644 index 59c64e6380..0000000000 --- a/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.no-ojdbc.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -services: - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle21-sink/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.ssl.yml b/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.ssl.yml index ddf39dcd65..0b4731913d 100644 --- a/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.ssl.yml +++ b/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.ssl.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle21-sink/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle21-sink/ssl/truststore.jks:/tmp/truststore.jks environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc diff --git a/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.yml b/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.yml index d90c81daf2..59c64e6380 100644 --- a/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.yml +++ b/connect/connect-jdbc-oracle21-sink/docker-compose.plaintext.yml @@ -16,7 +16,5 @@ services: connect: depends_on: - oracle - volumes: - - ../../connect/connect-jdbc-oracle21-sink/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls-db-auth.sh b/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls-db-auth.sh index 523eb7e5cb..ca58e65aa2 100755 --- a/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls-db-auth.sh @@ -10,30 +10,9 @@ create_or_get_oracle_image "LINUX.X64_213000_db_home.zip" "../../connect/connect # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d oracle -fi - +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 log "Oracle DB has started!" @@ -158,20 +137,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls.sh b/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls.sh index a3cf92126f..dd39618847 100755 --- a/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls.sh +++ b/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls.sh @@ -10,30 +10,9 @@ create_or_get_oracle_image "LINUX.X64_213000_db_home.zip" "../../connect/connect # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d oracle -fi - +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 log "Oracle DB has started!" @@ -152,20 +131,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle21-sink/oracle21-sink-ssl.sh b/connect/connect-jdbc-oracle21-sink/oracle21-sink-ssl.sh index de4dd518da..bbd5c88b16 100755 --- a/connect/connect-jdbc-oracle21-sink/oracle21-sink-ssl.sh +++ b/connect/connect-jdbc-oracle21-sink/oracle21-sink-ssl.sh @@ -10,30 +10,9 @@ create_or_get_oracle_image "LINUX.X64_213000_db_home.zip" "../../connect/connect # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" up -d oracle -fi - +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 log "Oracle DB has started!" @@ -124,20 +103,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle21-sink/oracle21-sink.sh b/connect/connect-jdbc-oracle21-sink/oracle21-sink.sh index 14d3dd206c..aea022ab7a 100755 --- a/connect/connect-jdbc-oracle21-sink/oracle21-sink.sh +++ b/connect/connect-jdbc-oracle21-sink/oracle21-sink.sh @@ -6,27 +6,8 @@ source ${DIR}/../../scripts/utils.sh create_or_get_oracle_image "LINUX.X64_213000_db_home.zip" "../../connect/connect-jdbc-oracle21-sink/ora-setup-scripts" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} +PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} -playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.no-ojdbc.yml" -fi playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 diff --git a/connect/connect-jdbc-oracle21-source/README.md b/connect/connect-jdbc-oracle21-source/README.md index f30defcbed..6697e50f19 100644 --- a/connect/connect-jdbc-oracle21-source/README.md +++ b/connect/connect-jdbc-oracle21-source/README.md @@ -6,7 +6,7 @@ Quickly test [JDBC Source](https://docs.confluent.io/current/connect/kafka-conne N.B: if you're a Confluent employee, please check this [link](https://confluent.slack.com/archives/C0116NM415F/p1636391410032900) and also [here](https://confluent.slack.com/archives/C0116NM415F/p1636389483030900). -* If you're using a JDBC connector version before `10.0.0`, you need to download Oracle Database 12.2.0.1 JDBC Driver `ojdbc8.jar`from this [page](https://www.oracle.com/database/technologies/jdbc-ucp-122-downloads.html) and place it in `./ojdbc8.jar` + Download Oracle Database 21c (21.3) for Linux x86-64 `LINUX.X64_213000_db_home.zip`from this [page](https://www.oracle.com/database/technologies/oracle21c-linux-downloads.html) and place it in `./LINUX.X64_213000_db_home.zip` diff --git a/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.mtls-db-auth.yml b/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.mtls-db-auth.yml index 34f5ce77ee..03643d97bf 100644 --- a/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.mtls-db-auth.yml +++ b/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.mtls-db-auth.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle21-source/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle21-source/mtls/truststore.jks:/tmp/truststore.jks - ../../connect/connect-jdbc-oracle21-source/mtls/keystore.jks:/tmp/keystore.jks environment: diff --git a/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.mtls.yml b/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.mtls.yml index 0607fd7ff2..b93b9206cd 100644 --- a/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.mtls.yml +++ b/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.mtls.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle21-source/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle21-source/mtls/truststore.jks:/tmp/truststore.jks - ../../connect/connect-jdbc-oracle21-source/mtls/keystore.jks:/tmp/keystore.jks environment: diff --git a/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.no-ojdbc-mtls.yml b/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.no-ojdbc-mtls.yml deleted file mode 100644 index 7e75bf26df..0000000000 --- a/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.no-ojdbc-mtls.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -services: - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle21-source/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - volumes: - - ../../connect/connect-jdbc-oracle21-source/mtls/truststore.jks:/tmp/truststore.jks - - ../../connect/connect-jdbc-oracle21-source/mtls/keystore.jks:/tmp/keystore.jks - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - -Djavax.net.ssl.keyStore=/tmp/keystore.jks - -Djavax.net.ssl.keyStorePassword=welcome123 - # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.no-ojdbc-ssl.yml b/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.no-ojdbc-ssl.yml deleted file mode 100644 index e22f6beb99..0000000000 --- a/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.no-ojdbc-ssl.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -services: - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle21-source/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - volumes: - - ../../connect/connect-jdbc-oracle21-source/ssl/truststore.jks:/tmp/truststore.jks - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.no-ojdbc.yml b/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.no-ojdbc.yml deleted file mode 100644 index 253c71e8e8..0000000000 --- a/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.no-ojdbc.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- -services: - - sql-datagen: - build: - context: ../../connect/connect-jdbc-oracle21-source/oracle-datagen/ - hostname: sql-datagen - container_name: sql-datagen - profiles: - - sql_datagen - volumes: - - ../../connect-jdbc-oracle21-source/oracle-datagen/target/sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar:/sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar - - oracle: - # You need to build this image first, following the instructions at - # https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md - image: ${ORACLE_IMAGE} - hostname: oracle - container_name: oracle - ports: - - "1521:1521" - volumes: - - ../../connect/connect-jdbc-oracle21-source/ora-setup-scripts:/opt/oracle/scripts/setup - environment: - ORACLE_PWD: Admin123 - - connect: - depends_on: - - oracle - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.ssl.yml b/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.ssl.yml index 4e7bc36997..5779c87fdc 100644 --- a/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.ssl.yml +++ b/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.ssl.yml @@ -17,7 +17,6 @@ services: depends_on: - oracle volumes: - - ../../connect/connect-jdbc-oracle21-source/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar - ../../connect/connect-jdbc-oracle21-source/ssl/truststore.jks:/tmp/truststore.jks environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc diff --git a/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.yml b/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.yml index 5e10b7e8e2..95cdd82f87 100644 --- a/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.yml +++ b/connect/connect-jdbc-oracle21-source/docker-compose.plaintext.yml @@ -27,7 +27,5 @@ services: connect: depends_on: - oracle - volumes: - - ../../connect/connect-jdbc-oracle21-source/ojdbc8.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/lib/ojdbc8.jar environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc \ No newline at end of file diff --git a/connect/connect-jdbc-oracle21-source/oracle21-mtls-db-auth.sh b/connect/connect-jdbc-oracle21-source/oracle21-mtls-db-auth.sh index 6659491424..ce6cab3406 100755 --- a/connect/connect-jdbc-oracle21-source/oracle21-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle21-source/oracle21-mtls-db-auth.sh @@ -10,29 +10,9 @@ create_or_get_oracle_image "LINUX.X64_213000_db_home.zip" "../../connect/connect # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d oracle -fi +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 log "Oracle DB has started!" @@ -191,20 +171,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle21-source/oracle21-mtls.sh b/connect/connect-jdbc-oracle21-source/oracle21-mtls.sh index eac44bc004..17bae21a11 100755 --- a/connect/connect-jdbc-oracle21-source/oracle21-mtls.sh +++ b/connect/connect-jdbc-oracle21-source/oracle21-mtls.sh @@ -10,29 +10,9 @@ create_or_get_oracle_image "LINUX.X64_213000_db_home.zip" "../../connect/connect # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d oracle -fi +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 log "Oracle DB has started!" @@ -185,20 +165,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle21-source/oracle21-ssl.sh b/connect/connect-jdbc-oracle21-source/oracle21-ssl.sh index 30735d70ee..0d21462698 100755 --- a/connect/connect-jdbc-oracle21-source/oracle21-ssl.sh +++ b/connect/connect-jdbc-oracle21-source/oracle21-ssl.sh @@ -10,29 +10,9 @@ create_or_get_oracle_image "LINUX.X64_213000_db_home.zip" "../../connect/connect # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d oracle -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" down -v --remove-orphans - log "Starting up oracle container to get generated cert from oracle server wallet" - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" up -d oracle -fi +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" down -v --remove-orphans +log "Starting up oracle container to get generated cert from oracle server wallet" +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 log "Oracle DB has started!" @@ -157,20 +137,12 @@ EOF log "Sleeping 60 seconds" sleep 60 -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d --quiet-pull +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d --quiet-pull - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" +command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" +playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" -else - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml" up -d --quiet-pull - - command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.no-ojdbc-ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" - playground state set run.docker_command "$command" -playground state set run.environment "plaintext" -fi +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" wait_container_ready diff --git a/connect/connect-jdbc-oracle21-source/oracle21.sh b/connect/connect-jdbc-oracle21-source/oracle21.sh index 40de27cb9d..3ac1feb68d 100755 --- a/connect/connect-jdbc-oracle21-source/oracle21.sh +++ b/connect/connect-jdbc-oracle21-source/oracle21.sh @@ -28,27 +28,8 @@ else log "🛑 SQL_DATAGEN is not set" fi -if [ ! -z "$CONNECTOR_TAG" ] -then - JDBC_CONNECTOR_VERSION=$CONNECTOR_TAG -else - JDBC_CONNECTOR_VERSION=$(docker run ${CP_CONNECT_IMAGE}:${CONNECT_TAG} cat /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc/manifest.json | jq -r '.version') -fi -log "JDBC Connector version is $JDBC_CONNECTOR_VERSION" -if ! version_gt $JDBC_CONNECTOR_VERSION "9.9.9"; then - get_3rdparty_file "ojdbc8.jar" - if [ ! -f ${DIR}/ojdbc8.jar ] - then - logerror "ERROR: ${DIR}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" - exit 1 - fi - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} +PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -else - log "ojdbc jar is shipped with connector (starting with 10.0.0)" - PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} -playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.no-ojdbc.yml" -fi playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 2500 log "Oracle DB has started!" From 44cbda95dc8911cf1f136c75d376d16226b42893 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 17 Jan 2025 09:12:17 +0100 Subject: [PATCH 168/659] wip --- secrets.tar.gpg | Bin 7836 -> 7833 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/secrets.tar.gpg b/secrets.tar.gpg index 184d381857d8f3df17668e56f48a10f00137d7e5..1c95bea9808dcc072b77b1cfa0ffc402c2c1b180 100644 GIT binary patch literal 7833 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 literal 7836 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 Date: Fri, 17 Jan 2025 13:54:39 +0100 Subject: [PATCH 169/659] fix --- connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh b/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh index 22f7a3559b..602ed8b300 100755 --- a/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh @@ -10,9 +10,9 @@ create_or_get_oracle_image "linuxx64_12201_database.zip" "../../connect/connect- # PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} #playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" -docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth-db-auth.yml" down -v --remove-orphans +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" down -v --remove-orphans log "Starting up oracle container to get generated cert from oracle server wallet" -docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth-db-auth.yml" up -d oracle +docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls-db-auth.yml" up -d oracle playground --output-level WARN container logs --container oracle --wait-for-log "DATABASE IS READY TO USE" --max-wait 900 log "Oracle DB has started!" From ee0b4a2f07ebc22c714ec02b2a8e3798e7acb15d Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 17 Jan 2025 14:17:59 +0100 Subject: [PATCH 170/659] fix --- .../dynamodb-sink-proxy.sh | 46 +------------------ 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/connect/connect-aws-dynamodb-sink/dynamodb-sink-proxy.sh b/connect/connect-aws-dynamodb-sink/dynamodb-sink-proxy.sh index d8f1485d6c..b349c86e15 100755 --- a/connect/connect-aws-dynamodb-sink/dynamodb-sink-proxy.sh +++ b/connect/connect-aws-dynamodb-sink/dynamodb-sink-proxy.sh @@ -10,51 +10,7 @@ then exit 111 fi -if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) -then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 -else - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] - then - log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" - export AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY - else - if [ -f $HOME/.aws/credentials ] - then - logwarn "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" - export AWS_ACCESS_KEY_ID=$( grep "^aws_access_key_id" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - export AWS_SECRET_ACCESS_KEY=$( grep "^aws_secret_access_key" $HOME/.aws/credentials | head -1 | awk -F'=' '{print $2;}' ) - fi - fi - if [ -z "$AWS_REGION" ] - then - AWS_REGION=$(aws configure get region | tr '\r' '\n') - if [ "$AWS_REGION" == "" ] - then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" - exit 1 - fi - fi -fi - -export AWS_CREDENTIALS_FILE_NAME=credentials -if [ ! -f $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME ] -then - log "generating $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME" - mkdir -p $HOME/.aws - sed -e "s|:AWS_ACCESS_KEY_ID:|$AWS_ACCESS_KEY_ID|g" \ - -e "s|:AWS_SECRET_ACCESS_KEY:|$AWS_SECRET_ACCESS_KEY|g" \ - ../../connect/connect-aws-dynamodb-sink/aws-credentials.template > $HOME/.aws/$AWS_CREDENTIALS_FILE_NAME -fi - -if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" -then - export CONNECT_CONTAINER_HOME_DIR="/home/appuser" -else - export CONNECT_CONTAINER_HOME_DIR="/root" -fi +handle_aws_credentials PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.proxy.yml" From f3c0952e1b370ef691545c53ede983cc6aa83bd2 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 17 Jan 2025 15:14:54 +0100 Subject: [PATCH 171/659] fix --- scripts/cli/playground | 2 ++ .../cli/src/commands/get-docker-compose.sh | 2 ++ scripts/cli/src/lib/utils_function.sh | 24 +++++++------------ 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index fdc7120233..727eb92fec 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -17998,6 +17998,8 @@ playground_get_docker_compose_command() { export CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) export ORACLE_IMAGE=$(docker inspect -f '{{.Config.Image}}' oracle 2> /dev/null) + handle_aws_credentials + docker_command=$(playground state get run.docker_command) if [ "$docker_command" == "" ] then diff --git a/scripts/cli/src/commands/get-docker-compose.sh b/scripts/cli/src/commands/get-docker-compose.sh index 4e5abdd054..73041741a4 100644 --- a/scripts/cli/src/commands/get-docker-compose.sh +++ b/scripts/cli/src/commands/get-docker-compose.sh @@ -3,6 +3,8 @@ export TAG=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d export CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) export ORACLE_IMAGE=$(docker inspect -f '{{.Config.Image}}' oracle 2> /dev/null) +handle_aws_credentials + docker_command=$(playground state get run.docker_command) if [ "$docker_command" == "" ] then diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 9b2d04cbbc..ff9c4bac5f 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -4289,15 +4289,7 @@ function maybe_set_azure_subscription () { } function handle_aws_credentials () { - - tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) - if [ -z "$PG_VERBOSE_MODE" ] - then - trap 'rm -rf $tmp_dir' EXIT - else - log "🐛📂 not deleting tmp dir $tmp_dir" - fi - export AWS_CREDENTIALS_FILE_NAME="$tmp_dir/credentials" + export AWS_CREDENTIALS_FILE_NAME="/tmp/aws_credentials" if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ -z $AWS_SESSION_TOKEN ] then @@ -4321,9 +4313,9 @@ function handle_aws_credentials () { fi cat << EOF > $AWS_CREDENTIALS_FILE_NAME - [default] - aws_access_key_id=$AWS_ACCESS_KEY_ID - aws_secret_access_key=$AWS_SECRET_ACCESS_KEY +[default] +aws_access_key_id=$AWS_ACCESS_KEY_ID +aws_secret_access_key=$AWS_SECRET_ACCESS_KEY EOF if [ -z "$AWS_REGION" ] then @@ -4364,10 +4356,10 @@ EOF export AWS_SESSION_TOKEN cat << EOF > $AWS_CREDENTIALS_FILE_NAME - [default] - aws_access_key_id=$AWS_ACCESS_KEY_ID - aws_secret_access_key=$AWS_SECRET_ACCESS_KEY - aws_session_token=$AWS_SESSION_TOKEN +[default] +aws_access_key_id=$AWS_ACCESS_KEY_ID +aws_secret_access_key=$AWS_SECRET_ACCESS_KEY +aws_session_token=$AWS_SESSION_TOKEN EOF elif grep -q "aws_session_token" $HOME/.aws/credentials then From 2ce634b329fd89a87c6d4c3cacdb9bb29d8738fb Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 20 Jan 2025 10:10:12 +0100 Subject: [PATCH 172/659] =?UTF-8?q?=F0=9F=90=9B=20Conduktor=20is=20broken?= =?UTF-8?q?=20#6218?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plaintext/conduktor/platform-config.yaml | 27 +++++++++----- environment/plaintext/docker-compose.yml | 35 ++++++++++++++----- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/environment/plaintext/conduktor/platform-config.yaml b/environment/plaintext/conduktor/platform-config.yaml index 2ffb09ce8e..396fc76fbc 100644 --- a/environment/plaintext/conduktor/platform-config.yaml +++ b/environment/plaintext/conduktor/platform-config.yaml @@ -1,5 +1,21 @@ organization: - name: kafka-docker-playground + name: conduktor + +database: + hosts: + - host: 'conduktor-postgresql' + port: 5432 + name: 'conduktor' + username: 'conduktor' + password: 'change_me' + connection_timeout: 30 # in seconds + +monitoring: + cortex-url: 'http://conduktor-monitoring:9009/' + alert-manager-url: 'http://conduktor-monitoring:9010/' + callback-url: 'http://conduktor-console:8080/monitoring/api/' + notifications-callback-url: 'http://localhost:8080' + clusters: - id: local name: My Cluster @@ -24,10 +40,5 @@ clusters: kafkaConnects: - url: "http://connect:8083" id: kafka-connect - name: kafkConnect -auth: - demo-users: - - email: admin - password: admin - groups: - - ADMIN + name: kafkConnect + diff --git a/environment/plaintext/docker-compose.yml b/environment/plaintext/docker-compose.yml index 5c27d96233..235207a719 100644 --- a/environment/plaintext/docker-compose.yml +++ b/environment/plaintext/docker-compose.yml @@ -578,20 +578,39 @@ services: profiles: - "kcat" - # https://github.com/conduktor/conduktor-platform/blob/main/doc/Configuration.md - conduktor: - image: conduktor/conduktor-platform:latest - hostname: conduktor - container_name: conduktor + conduktor-postgresql: + image: postgres:14 + hostname: conduktor-postgresql + container_name: conduktor-postgresql + environment: + POSTGRES_DB: "conduktor" + POSTGRES_USER: "conduktor" + POSTGRES_PASSWORD: "change_me" + profiles: + - "conduktor" + + conduktor-console: + image: conduktor/conduktor-console:1.30.0 + hostname: conduktor-console + container_name: conduktor-console depends_on: - - broker + - conduktor-postgresql ports: - - 8080:80 + - "8080:8080" volumes: - ../../environment/plaintext/conduktor/platform-config.yaml:/tmp/platform-config.yaml environment: CDK_IN_CONF_FILE: /tmp/platform-config.yaml - RUN_MODE: "nano" + profiles: + - "conduktor" + + conduktor-monitoring: + image: conduktor/conduktor-console-cortex:1.30.0 + hostname: conduktor-monitoring + container_name: conduktor-monitoring + environment: + # Connection to the Console container + CDK_CONSOLE-URL: "http://conduktor-console:8080" profiles: - "conduktor" From bd6c7863d8f7e27b6e06b7eb4655e034384a3a69 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 20 Jan 2025 10:35:44 +0100 Subject: [PATCH 173/659] =?UTF-8?q?=F0=9F=90=9B=20Conduktor=20is=20broken?= =?UTF-8?q?=20#6218?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2way-ssl/conduktor/platform-config.yaml | 35 ++++++++++++------ environment/2way-ssl/docker-compose.yml | 37 +++++++++++++++++-- 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/environment/2way-ssl/conduktor/platform-config.yaml b/environment/2way-ssl/conduktor/platform-config.yaml index 2e192b3814..a4ed62c972 100644 --- a/environment/2way-ssl/conduktor/platform-config.yaml +++ b/environment/2way-ssl/conduktor/platform-config.yaml @@ -1,10 +1,26 @@ organization: - name: kafka-docker-playground + name: conduktor + +database: + hosts: + - host: 'conduktor-postgresql' + port: 5432 + name: 'conduktor' + username: 'conduktor' + password: 'change_me' + connection_timeout: 30 # in seconds + +monitoring: + cortex-url: 'http://conduktor-monitoring:9009/' + alert-manager-url: 'http://conduktor-monitoring:9010/' + callback-url: 'http://conduktor-console:8080/monitoring/api/' + notifications-callback-url: 'http://localhost:8080' + clusters: - id: local name: My Cluster color: "#0013E7" - ignoreUntrustedCertificate: false + ignoreUntrustedCertificate: true bootstrapServers: "broker:9092" properties: | client.id=conduktor @@ -12,14 +28,16 @@ clusters: request.timeout.ms=5000 ssl.truststore.location=/etc/kafka/secrets/kafka.conduktor.truststore.jks ssl.truststore.password=confluent + ssl.truststore.type=JKS ssl.keystore.location=/etc/kafka/secrets/kafka.conduktor.keystore.jks ssl.keystore.password=confluent - ssl.key.password=confluent + ssl.keystore.type=JKS + ssl.key.password=confluent security.protocol=SSL schemaRegistry: id: Local SR url: "https://schema-registry:8081" - ignoreUntrustedCertificate: false + ignoreUntrustedCertificate: true properties: | acks=all client.id=conduktor @@ -35,10 +53,5 @@ clusters: kafkaConnects: - url: "https://connect:8083" id: kafka-connect - name: kafkConnect -auth: - demo-users: - - email: admin - password: admin - groups: - - ADMIN + ignoreUntrustedCertificate: true + name: kafkaConnect \ No newline at end of file diff --git a/environment/2way-ssl/docker-compose.yml b/environment/2way-ssl/docker-compose.yml index dc03d7fb14..a7398206d8 100644 --- a/environment/2way-ssl/docker-compose.yml +++ b/environment/2way-ssl/docker-compose.yml @@ -366,8 +366,39 @@ services: -Djavax.net.ssl.keyStore=/etc/kafka/secrets/kafka.control-center.keystore.jks -Djavax.net.ssl.keyStorePassword=confluent - # https://github.com/conduktor/conduktor-platform/blob/main/doc/Configuration.md - conduktor: + conduktor-postgresql: + image: postgres:14 + hostname: conduktor-postgresql + container_name: conduktor-postgresql + environment: + POSTGRES_DB: "conduktor" + POSTGRES_USER: "conduktor" + POSTGRES_PASSWORD: "change_me" + profiles: + - "conduktor" + + conduktor-console: + image: conduktor/conduktor-console:1.30.0 + hostname: conduktor-console + container_name: conduktor-console + depends_on: + - conduktor-postgresql + ports: + - "8080:8080" volumes: - ../../environment/2way-ssl/conduktor/platform-config.yaml:/tmp/platform-config.yaml - - ../../environment/2way-ssl/security:/etc/kafka/secrets \ No newline at end of file + - ../../environment/2way-ssl/security:/etc/kafka/secrets + environment: + CDK_IN_CONF_FILE: /tmp/platform-config.yaml + profiles: + - "conduktor" + + conduktor-monitoring: + image: conduktor/conduktor-console-cortex:1.30.0 + hostname: conduktor-monitoring + container_name: conduktor-monitoring + environment: + # Connection to the Console container + CDK_CONSOLE-URL: "http://conduktor-console:8080" + profiles: + - "conduktor" From a6c31e08b6139ddf130c675d0024c84edc25f707 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 20 Jan 2025 11:16:34 +0100 Subject: [PATCH 174/659] =?UTF-8?q?=F0=9F=90=9B=20Conduktor=20is=20broken?= =?UTF-8?q?=20#6218?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kerberos/conduktor/platform-config.yaml | 26 +++++++---- environment/kerberos/docker-compose.yml | 44 ++++++++++++++----- 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/environment/kerberos/conduktor/platform-config.yaml b/environment/kerberos/conduktor/platform-config.yaml index 22a8f96c7d..fb21a9819a 100644 --- a/environment/kerberos/conduktor/platform-config.yaml +++ b/environment/kerberos/conduktor/platform-config.yaml @@ -1,5 +1,21 @@ organization: - name: kafka-docker-playground + name: conduktor + +database: + hosts: + - host: 'conduktor-postgresql' + port: 5432 + name: 'conduktor' + username: 'conduktor' + password: 'change_me' + connection_timeout: 30 # in seconds + +monitoring: + cortex-url: 'http://conduktor-monitoring:9009/' + alert-manager-url: 'http://conduktor-monitoring:9010/' + callback-url: 'http://conduktor-console:8080/monitoring/api/' + notifications-callback-url: 'http://localhost:8080' + clusters: - id: local name: My Cluster @@ -28,10 +44,4 @@ clusters: kafkaConnects: - url: "http://connect:8083" id: kafka-connect - name: kafkConnect -auth: - demo-users: - - email: admin - password: admin - groups: - - ADMIN + name: kafkaConnect \ No newline at end of file diff --git a/environment/kerberos/docker-compose.yml b/environment/kerberos/docker-compose.yml index e2eee86c1c..b0c61e961f 100644 --- a/environment/kerberos/docker-compose.yml +++ b/environment/kerberos/docker-compose.yml @@ -458,20 +458,44 @@ services: CONTROL_CENTER_KAFKA_MYCLUSTER_SASL_MECHANISM: GSSAPI CONTROL_CENTER_KAFKA_MYCLUSTER_SASL_KERBEROS_SERVICE_NAME: kafka - # https://github.com/conduktor/conduktor-platform/blob/main/doc/Configuration.md - conduktor: + conduktor-postgresql: + image: postgres:14 + hostname: conduktor-postgresql + container_name: conduktor-postgresql + environment: + POSTGRES_DB: "conduktor" + POSTGRES_USER: "conduktor" + POSTGRES_PASSWORD: "change_me" + profiles: + - "conduktor" + + conduktor-console: + image: conduktor/conduktor-console:1.30.0 hostname: conduktor.kerberos-demo.local + container_name: conduktor-console + depends_on: + - conduktor-postgresql + ports: + - "8080:8080" volumes: - ../../environment/kerberos/conduktor/platform-config.yaml:/tmp/platform-config.yaml - secret:/var/lib/secret - - ../../environment/kerberos/kdc/krb5.conf:/etc/kdc/krb5.conf -# FIXTHIS: Caused by: org.apache.kafka.common.KafkaException: javax.security.auth.login.LoginException: Cannot locate KDC -# at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:172) -# at org.apache.kafka.common.network.ChannelBuilders.create(ChannelBuilders.java:157) -# at org.apache.kafka.common.network.ChannelBuilders.clientChannelBuilder(ChannelBuilders.java:73) -# at org.apache.kafka.clients.ClientUtils.createChannelBuilder(ClientUtils.java:105) -# at org.apache.kafka.clients.consumer.KafkaConsumer.(KafkaConsumer.java:743) -# ... 25 common frames omitted + - ../../environment/kerberos/kdc/krb5.conf:/etc/krb5.conf + environment: + CDK_IN_CONF_FILE: /tmp/platform-config.yaml + KRB5_CONFIG: /etc/krb5.conf + profiles: + - "conduktor" + + conduktor-monitoring: + image: conduktor/conduktor-console-cortex:1.30.0 + hostname: conduktor-monitoring + container_name: conduktor-monitoring + environment: + # Connection to the Console container + CDK_CONSOLE-URL: "http://conduktor-console:8080" + profiles: + - "conduktor" volumes: secret: {} From af75308e8447f33eacf4f90d0236c43339abfd59 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 20 Jan 2025 11:24:54 +0100 Subject: [PATCH 175/659] =?UTF-8?q?=F0=9F=90=9B=20Conduktor=20is=20broken?= =?UTF-8?q?=20#6218?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sasl-plain/conduktor/platform-config.yaml | 26 +++++++++---- environment/sasl-plain/docker-compose.yml | 37 +++++++++++++++++-- scripts/cli/src/lib/utils_function.sh | 2 +- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/environment/sasl-plain/conduktor/platform-config.yaml b/environment/sasl-plain/conduktor/platform-config.yaml index 3d788061d4..304953949c 100644 --- a/environment/sasl-plain/conduktor/platform-config.yaml +++ b/environment/sasl-plain/conduktor/platform-config.yaml @@ -1,5 +1,20 @@ organization: - name: kafka-docker-playground + name: conduktor + +database: + hosts: + - host: 'conduktor-postgresql' + port: 5432 + name: 'conduktor' + username: 'conduktor' + password: 'change_me' + connection_timeout: 30 # in seconds + +monitoring: + cortex-url: 'http://conduktor-monitoring:9009/' + alert-manager-url: 'http://conduktor-monitoring:9010/' + callback-url: 'http://conduktor-console:8080/monitoring/api/' + notifications-callback-url: 'http://localhost:8080' clusters: - id: local name: My Cluster @@ -27,10 +42,5 @@ clusters: kafkaConnects: - url: "http://connect:8083" id: kafka-connect - name: kafkConnect -auth: - demo-users: - - email: admin - password: admin - groups: - - ADMIN + name: kafkaConnect + diff --git a/environment/sasl-plain/docker-compose.yml b/environment/sasl-plain/docker-compose.yml index ae0897f306..7c03328745 100644 --- a/environment/sasl-plain/docker-compose.yml +++ b/environment/sasl-plain/docker-compose.yml @@ -285,7 +285,38 @@ services: password=\"client-secret\";" CONTROL_CENTER_KAFKA_MYCLUSTER_SASL_MECHANISM: PLAIN - # https://github.com/conduktor/conduktor-platform/blob/main/doc/Configuration.md - conduktor: + conduktor-postgresql: + image: postgres:14 + hostname: conduktor-postgresql + container_name: conduktor-postgresql + environment: + POSTGRES_DB: "conduktor" + POSTGRES_USER: "conduktor" + POSTGRES_PASSWORD: "change_me" + profiles: + - "conduktor" + + conduktor-console: + image: conduktor/conduktor-console:1.30.0 + hostname: conduktor-console + container_name: conduktor-console + depends_on: + - conduktor-postgresql + ports: + - "8080:8080" volumes: - - ../../environment/sasl-plain/conduktor/platform-config.yaml:/tmp/platform-config.yaml \ No newline at end of file + - ../../environment/sasl-plain/conduktor/platform-config.yaml:/tmp/platform-config.yaml + environment: + CDK_IN_CONF_FILE: /tmp/platform-config.yaml + profiles: + - "conduktor" + + conduktor-monitoring: + image: conduktor/conduktor-console-cortex:1.30.0 + hostname: conduktor-monitoring + container_name: conduktor-monitoring + environment: + # Connection to the Console container + CDK_CONSOLE-URL: "http://conduktor-console:8080" + profiles: + - "conduktor" diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index ff9c4bac5f..06c16c65b5 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -564,7 +564,7 @@ function set_profiles() { playground state del flags.ENABLE_CONDUKTOR else log "🐺 conduktor is enabled" - log "Use http://localhost:8080/console (admin/admin) to login" + log "Use http://localhost:8080/console to login" profile_conduktor_command="--profile conduktor" playground state set flags.ENABLE_CONDUKTOR 1 fi From b0588e3a8614f30ea8a041c41975309241dea2d1 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 20 Jan 2025 11:34:20 +0100 Subject: [PATCH 176/659] =?UTF-8?q?=F0=9F=90=9B=20Conduktor=20is=20broken?= =?UTF-8?q?=20#6218?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sasl-scram/conduktor/platform-config.yaml | 23 ++++++++---- environment/sasl-scram/docker-compose.yml | 37 +++++++++++++++++-- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/environment/sasl-scram/conduktor/platform-config.yaml b/environment/sasl-scram/conduktor/platform-config.yaml index 7a30c6ea79..7da7cd914b 100644 --- a/environment/sasl-scram/conduktor/platform-config.yaml +++ b/environment/sasl-scram/conduktor/platform-config.yaml @@ -1,5 +1,20 @@ organization: - name: kafka-docker-playground + name: conduktor + +database: + hosts: + - host: 'conduktor-postgresql' + port: 5432 + name: 'conduktor' + username: 'conduktor' + password: 'change_me' + connection_timeout: 30 # in seconds + +monitoring: + cortex-url: 'http://conduktor-monitoring:9009/' + alert-manager-url: 'http://conduktor-monitoring:9010/' + callback-url: 'http://conduktor-console:8080/monitoring/api/' + notifications-callback-url: 'http://localhost:8080' clusters: - id: local name: My Cluster @@ -28,9 +43,3 @@ clusters: - url: "http://connect:8083" id: kafka-connect name: kafkConnect -auth: - demo-users: - - email: admin - password: admin - groups: - - ADMIN diff --git a/environment/sasl-scram/docker-compose.yml b/environment/sasl-scram/docker-compose.yml index 6208a63967..17db51e379 100644 --- a/environment/sasl-scram/docker-compose.yml +++ b/environment/sasl-scram/docker-compose.yml @@ -234,7 +234,38 @@ services: password=\"client-secret\";" CONTROL_CENTER_KAFKA_MYCLUSTER_SASL_MECHANISM: SCRAM-SHA-256 - # https://github.com/conduktor/conduktor-platform/blob/main/doc/Configuration.md - conduktor: + conduktor-postgresql: + image: postgres:14 + hostname: conduktor-postgresql + container_name: conduktor-postgresql + environment: + POSTGRES_DB: "conduktor" + POSTGRES_USER: "conduktor" + POSTGRES_PASSWORD: "change_me" + profiles: + - "conduktor" + + conduktor-console: + image: conduktor/conduktor-console:1.30.0 + hostname: conduktor-console + container_name: conduktor-console + depends_on: + - conduktor-postgresql + ports: + - "8080:8080" volumes: - - ../../environment/sasl-scram/conduktor/platform-config.yaml:/tmp/platform-config.yaml \ No newline at end of file + - ../../environment/sasl-scram/conduktor/platform-config.yaml:/tmp/platform-config.yaml + environment: + CDK_IN_CONF_FILE: /tmp/platform-config.yaml + profiles: + - "conduktor" + + conduktor-monitoring: + image: conduktor/conduktor-console-cortex:1.30.0 + hostname: conduktor-monitoring + container_name: conduktor-monitoring + environment: + # Connection to the Console container + CDK_CONSOLE-URL: "http://conduktor-console:8080" + profiles: + - "conduktor" \ No newline at end of file From 4aec3be19bf45d68cf3ee63c8b9816342170b2a8 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 20 Jan 2025 11:46:59 +0100 Subject: [PATCH 177/659] =?UTF-8?q?=F0=9F=90=9B=20Conduktor=20is=20broken?= =?UTF-8?q?=20#6218?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sasl-ssl/conduktor/platform-config.yaml | 34 ++++++++++++----- environment/sasl-ssl/docker-compose.yml | 37 +++++++++++++++++-- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/environment/sasl-ssl/conduktor/platform-config.yaml b/environment/sasl-ssl/conduktor/platform-config.yaml index c5860dbfbe..3991d1aab8 100644 --- a/environment/sasl-ssl/conduktor/platform-config.yaml +++ b/environment/sasl-ssl/conduktor/platform-config.yaml @@ -1,10 +1,26 @@ organization: - name: kafka-docker-playground + name: conduktor + +database: + hosts: + - host: 'conduktor-postgresql' + port: 5432 + name: 'conduktor' + username: 'conduktor' + password: 'change_me' + connection_timeout: 30 # in seconds + +monitoring: + cortex-url: 'http://conduktor-monitoring:9009/' + alert-manager-url: 'http://conduktor-monitoring:9010/' + callback-url: 'http://conduktor-console:8080/monitoring/api/' + notifications-callback-url: 'http://localhost:8080' + clusters: - id: local name: My Cluster color: "#0013E7" - ignoreUntrustedCertificate: false + ignoreUntrustedCertificate: true bootstrapServers: "broker:9092" properties: | client.id=conduktor @@ -12,8 +28,10 @@ clusters: request.timeout.ms=5000 ssl.truststore.location=/etc/kafka/secrets/kafka.conduktor.truststore.jks ssl.truststore.password=confluent + ssl.truststore.type=JKS ssl.keystore.location=/etc/kafka/secrets/kafka.conduktor.keystore.jks ssl.keystore.password=confluent + ssl.keystore.type=JKS ssl.key.password=confluent security.protocol=SASL_SSL sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="client" password="client-secret"; @@ -21,7 +39,7 @@ clusters: schemaRegistry: id: Local SR url: "https://schema-registry:8081" - ignoreUntrustedCertificate: false + ignoreUntrustedCertificate: true properties: | acks=all client.id=conduktor @@ -37,10 +55,6 @@ clusters: kafkaConnects: - url: "https://connect:8083" id: kafka-connect - name: kafkConnect -auth: - demo-users: - - email: admin - password: admin - groups: - - ADMIN + name: kafkaConnect + ignoreUntrustedCertificate: true + diff --git a/environment/sasl-ssl/docker-compose.yml b/environment/sasl-ssl/docker-compose.yml index ae8633c56c..59ce153dce 100644 --- a/environment/sasl-ssl/docker-compose.yml +++ b/environment/sasl-ssl/docker-compose.yml @@ -466,8 +466,39 @@ services: -Djavax.net.ssl.keyStore=/etc/kafka/secrets/kafka.control-center.keystore.jks -Djavax.net.ssl.keyStorePassword=confluent - # https://github.com/conduktor/conduktor-platform/blob/main/doc/Configuration.md - conduktor: + conduktor-postgresql: + image: postgres:14 + hostname: conduktor-postgresql + container_name: conduktor-postgresql + environment: + POSTGRES_DB: "conduktor" + POSTGRES_USER: "conduktor" + POSTGRES_PASSWORD: "change_me" + profiles: + - "conduktor" + + conduktor-console: + image: conduktor/conduktor-console:1.30.0 + hostname: conduktor-console + container_name: conduktor-console + depends_on: + - conduktor-postgresql + ports: + - "8080:8080" volumes: - ../../environment/sasl-ssl/conduktor/platform-config.yaml:/tmp/platform-config.yaml - - ../../environment/sasl-ssl/security:/etc/kafka/secrets \ No newline at end of file + - ../../environment/sasl-ssl/security:/etc/kafka/secrets + environment: + CDK_IN_CONF_FILE: /tmp/platform-config.yaml + profiles: + - "conduktor" + + conduktor-monitoring: + image: conduktor/conduktor-console-cortex:1.30.0 + hostname: conduktor-monitoring + container_name: conduktor-monitoring + environment: + # Connection to the Console container + CDK_CONSOLE-URL: "http://conduktor-console:8080" + profiles: + - "conduktor" From c1a0807b55feef6b32bdd0ab996013d36f66ef23 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 20 Jan 2025 12:15:36 +0100 Subject: [PATCH 178/659] =?UTF-8?q?=F0=9F=90=9B=20Conduktor=20is=20broken?= =?UTF-8?q?=20#6218?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../conduktor/platform-config.yaml | 37 +++++++++++----- environment/ssl_kerberos/docker-compose.yml | 44 ++++++++++++++----- 2 files changed, 59 insertions(+), 22 deletions(-) diff --git a/environment/ssl_kerberos/conduktor/platform-config.yaml b/environment/ssl_kerberos/conduktor/platform-config.yaml index 52ef5483d1..1549b3fd31 100644 --- a/environment/ssl_kerberos/conduktor/platform-config.yaml +++ b/environment/ssl_kerberos/conduktor/platform-config.yaml @@ -1,10 +1,26 @@ organization: - name: kafka-docker-playground + name: conduktor + +database: + hosts: + - host: 'conduktor-postgresql' + port: 5432 + name: 'conduktor' + username: 'conduktor' + password: 'change_me' + connection_timeout: 30 # in seconds + +monitoring: + cortex-url: 'http://conduktor-monitoring:9009/' + alert-manager-url: 'http://conduktor-monitoring:9010/' + callback-url: 'http://conduktor-console:8080/monitoring/api/' + notifications-callback-url: 'http://localhost:8080' + clusters: - id: local name: My Cluster color: "#0013E7" - ignoreUntrustedCertificate: false + ignoreUntrustedCertificate: true bootstrapServers: "broker:9092" properties: | client.id=conduktor @@ -12,8 +28,10 @@ clusters: request.timeout.ms=5000 ssl.truststore.location=/etc/kafka/secrets/kafka.conduktor.truststore.jks ssl.truststore.password=confluent + ssl.truststore.type=JKS ssl.keystore.location=/etc/kafka/secrets/kafka.conduktor.keystore.jks ssl.keystore.password=confluent + ssl.keystore.type=JKS ssl.key.password=confluent sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab="/var/lib/secret/kafka-controlcenter.key" principal="controlcenter@TEST.CONFLUENT.IO"; sasl.mechanism=GSSAPI @@ -21,8 +39,8 @@ clusters: sasl.kerberos.service.name=kafka schemaRegistry: id: Local SR - url: "https://schema-registry:8081" - ignoreUntrustedCertificate: false + url: "http://schema-registry:8081" + ignoreUntrustedCertificate: true properties: | acks=all client.id=conduktor @@ -36,12 +54,7 @@ clusters: labels: env: default kafkaConnects: - - url: "https://connect:8083" + - url: "http://connect:8083" id: kafka-connect - name: kafkConnect -auth: - demo-users: - - email: admin - password: admin - groups: - - ADMIN + name: kafkaConnect + ignoreUntrustedCertificate: true diff --git a/environment/ssl_kerberos/docker-compose.yml b/environment/ssl_kerberos/docker-compose.yml index a71063ec86..d9fc1a483d 100644 --- a/environment/ssl_kerberos/docker-compose.yml +++ b/environment/ssl_kerberos/docker-compose.yml @@ -563,21 +563,45 @@ services: CONTROL_CENTER_KAFKA_MYCLUSTER_SSL_KEYSTORE_PASSWORD: confluent CONTROL_CENTER_KAFKA_MYCLUSTER_SSL_KEY_PASSWORD: confluent - # https://github.com/conduktor/conduktor-platform/blob/main/doc/Configuration.md - conduktor: + conduktor-postgresql: + image: postgres:14 + hostname: conduktor-postgresql + container_name: conduktor-postgresql + environment: + POSTGRES_DB: "conduktor" + POSTGRES_USER: "conduktor" + POSTGRES_PASSWORD: "change_me" + profiles: + - "conduktor" + + conduktor-console: + image: conduktor/conduktor-console:1.30.0 hostname: conduktor.kerberos-demo.local + container_name: conduktor-console + depends_on: + - conduktor-postgresql + ports: + - "8080:8080" volumes: - ../../environment/ssl_kerberos/conduktor/platform-config.yaml:/tmp/platform-config.yaml - secret:/var/lib/secret - - ../../environment/ssl_kerberos/kdc/krb5.conf:/etc/kdc/krb5.conf + - ../../environment/ssl_kerberos/kdc/krb5.conf:/etc/krb5.conf - ../../environment/ssl_kerberos/security:/etc/kafka/secrets -# FIXTHIS: Caused by: org.apache.kafka.common.KafkaException: javax.security.auth.login.LoginException: Cannot locate KDC -# at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:172) -# at org.apache.kafka.common.network.ChannelBuilders.create(ChannelBuilders.java:157) -# at org.apache.kafka.common.network.ChannelBuilders.clientChannelBuilder(ChannelBuilders.java:73) -# at org.apache.kafka.clients.ClientUtils.createChannelBuilder(ClientUtils.java:105) -# at org.apache.kafka.clients.consumer.KafkaConsumer.(KafkaConsumer.java:743) -# ... 25 common frames omitted + environment: + CDK_IN_CONF_FILE: /tmp/platform-config.yaml + KRB5_CONFIG: /etc/krb5.conf + profiles: + - "conduktor" + + conduktor-monitoring: + image: conduktor/conduktor-console-cortex:1.30.0 + hostname: conduktor-monitoring + container_name: conduktor-monitoring + environment: + # Connection to the Console container + CDK_CONSOLE-URL: "http://conduktor-console:8080" + profiles: + - "conduktor" volumes: secret: {} From b52ddc60b448f61d0fb7353b4d4a9b99a4ae4eaa Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 20 Jan 2025 12:19:33 +0100 Subject: [PATCH 179/659] =?UTF-8?q?=F0=9F=90=9B=20Conduktor=20is=20broken?= =?UTF-8?q?=20#6218?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 727eb92fec..a29f04cd72 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8742,7 +8742,7 @@ function set_profiles() { playground state del flags.ENABLE_CONDUKTOR else log "🐺 conduktor is enabled" - log "Use http://localhost:8080/console (admin/admin) to login" + log "Use http://localhost:8080/console to login" profile_conduktor_command="--profile conduktor" playground state set flags.ENABLE_CONDUKTOR 1 fi @@ -12400,15 +12400,7 @@ function maybe_set_azure_subscription () { } function handle_aws_credentials () { - - tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) - if [ -z "$PG_VERBOSE_MODE" ] - then - trap 'rm -rf $tmp_dir' EXIT - else - log "🐛📂 not deleting tmp dir $tmp_dir" - fi - export AWS_CREDENTIALS_FILE_NAME="$tmp_dir/credentials" + export AWS_CREDENTIALS_FILE_NAME="/tmp/aws_credentials" if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ -z $AWS_SESSION_TOKEN ] then @@ -12433,9 +12425,9 @@ function handle_aws_credentials () { fi cat << EOF > $AWS_CREDENTIALS_FILE_NAME - [default] - aws_access_key_id=$AWS_ACCESS_KEY_ID - aws_secret_access_key=$AWS_SECRET_ACCESS_KEY +[default] +aws_access_key_id=$AWS_ACCESS_KEY_ID +aws_secret_access_key=$AWS_SECRET_ACCESS_KEY EOF if [ -z "$AWS_REGION" ] then @@ -12476,10 +12468,10 @@ EOF export AWS_SESSION_TOKEN cat << EOF > $AWS_CREDENTIALS_FILE_NAME - [default] - aws_access_key_id=$AWS_ACCESS_KEY_ID - aws_secret_access_key=$AWS_SECRET_ACCESS_KEY - aws_session_token=$AWS_SESSION_TOKEN +[default] +aws_access_key_id=$AWS_ACCESS_KEY_ID +aws_secret_access_key=$AWS_SECRET_ACCESS_KEY +aws_session_token=$AWS_SESSION_TOKEN EOF elif grep -q "aws_session_token" $HOME/.aws/credentials then From bc027daa1cd6fdf43eec5549feaa5908b0fddc4f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 22 Jan 2025 10:09:28 +0100 Subject: [PATCH 180/659] update --- secrets.tar.gpg | Bin 7833 -> 7834 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/secrets.tar.gpg b/secrets.tar.gpg index 1c95bea9808dcc072b77b1cfa0ffc402c2c1b180..ca3bef27d8ac745f1de8e9f770c182b0762b65ba 100644 GIT binary patch literal 7834 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 literal 7833 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 From f20adabe5c03bdc5189db13dd07f1bc969933bb8 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 22 Jan 2025 11:43:14 +0100 Subject: [PATCH 181/659] fix for #6221 --- .../connect-jdbc-aws-redshift-source/redshift-jdbc-source.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connect/connect-jdbc-aws-redshift-source/redshift-jdbc-source.sh b/connect/connect-jdbc-aws-redshift-source/redshift-jdbc-source.sh index aa90a883ba..1ba97248e0 100755 --- a/connect/connect-jdbc-aws-redshift-source/redshift-jdbc-source.sh +++ b/connect/connect-jdbc-aws-redshift-source/redshift-jdbc-source.sh @@ -104,7 +104,7 @@ playground connector create-or-update --connector redshift-jdbc-source << EOF { "connector.class": "io.confluent.connect.jdbc.JdbcSourceConnector", "tasks.max": "1", - "connection.url": "jdbc:redshift://$CLUSTER:5439/dev?user=masteruser&password=myPassword1&ssl=false", + "connection.url": "jdbc:redshift://$CLUSTER:5439/dev?user=masteruser&password=myPassword1", "table.whitelist": "customers", "mode": "timestamp+incrementing", "timestamp.column.name": "update_ts", From 0461394bc6468189d9767a086c2896103fa84ffc Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 22 Jan 2025 20:26:15 +0100 Subject: [PATCH 182/659] open_file_with_editor --- scripts/cli/playground | 175 +++--------------- .../src/commands/connector/offsets/alter.sh | 6 +- .../connector/show-config-parameters.sh | 16 +- scripts/cli/src/commands/connector/update.sh | 2 +- scripts/cli/src/commands/container/logs.sh | 18 +- scripts/cli/src/commands/debug/thread-dump.sh | 16 +- scripts/cli/src/commands/open.sh | 16 +- scripts/cli/src/commands/repro/bootstrap.sh | 21 +-- scripts/cli/src/commands/run.sh | 35 +--- scripts/cli/src/commands/update-version.sh | 16 +- scripts/cli/src/lib/cli_function.sh | 13 ++ scripts/cli/src/lib/utils_function.sh | 16 +- 12 files changed, 60 insertions(+), 290 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index a29f04cd72..fc1fa5fb0c 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -7981,6 +7981,19 @@ function check_for_ec2_instance_running() { fi } +function open_file_with_editor() { + filename="$1" + editor=$(playground config get editor) + if [ "$editor" != "" ] && command -v "$editor" > /dev/null + then + log "📖 opening ${filename} using configured editor \"$editor\" (you can change editor by using \"playground config set editor \")" + $editor ${filename} + else + logerror "❌ editor \"$editor\" is not installed - you can change editor by using \"playground config set editor \"" + exit 1 + fi +} + # src/lib/colors.sh print_in_color() { local color="$1" @@ -9335,21 +9348,7 @@ done if [[ -n "$open" ]] then - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening /tmp/jmx_metrics.log using configured editor $editor" - $editor /tmp/jmx_metrics.log - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening /tmp/jmx_metrics.log with code (default) - you can change editor by using playground config editor " - code /tmp/jmx_metrics.log - fi - fi + open_file_with_editor "/tmp/jmx_metrics.log" fi } @@ -14172,23 +14171,8 @@ playground_run_command() { if [[ -n "$open" ]] then - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening ${test_file} using configured editor $editor" - $editor ${test_file} - check_if_continue - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${test_file} with code (default) - you can change editor by using playground config editor " - code ${test_file} - check_if_continue - fi - fi + open_file_with_editor "${test_file}" + check_if_continue fi if [ $interactive_mode == 1 ] @@ -14735,21 +14719,7 @@ playground_run_command() { if [[ $res == *"$MENU_OPEN_FILE"* ]] then - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening ${test_file} using configured editor $editor" - $editor ${test_file} - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${test_file} with code (default) - you can change editor by using playground config editor " - code ${test_file} - fi - fi + open_file_with_editor "${test_file}" fi if [[ $res == *"$MENU_OPEN_DOCS"* ]] @@ -15848,21 +15818,7 @@ playground_update_version_command() { if [[ $res == *"$MENU_OPEN_FILE"* ]] then - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening ${test_file} using configured editor $editor" - $editor ${test_file} - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${test_file} with code (default) - you can change editor by using playground config editor " - code ${test_file} - fi - fi + open_file_with_editor "${test_file}" fi if [[ $res == *"$MENU_OPEN_DOCS"* ]] @@ -16061,21 +16017,7 @@ playground_open_command() { fi fi - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening ${test_file} using configured editor $editor" - $editor ${test_file} - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${test_file} with code (default) - you can change editor by using playground config editor " - code ${test_file} - fi - fi + open_file_with_editor "${test_file}" } # :command.function @@ -17140,7 +17082,7 @@ playground_repro_bootstrap_command() { else if [[ $(type code 2>&1) =~ "not found" ]] then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " + logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" exit 1 else log "✨ Copy and paste the schema you want to use for the key, save and close the file to continue" @@ -17221,7 +17163,6 @@ playground_repro_bootstrap_command() { if [[ -n "$schema_file_value" ]] then - editor=$(playground config get editor) if [ "$editor" != "" ] then @@ -17235,7 +17176,7 @@ playground_repro_bootstrap_command() { else if [[ $(type code 2>&1) =~ "not found" ]] then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " + logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" exit 1 else log "✨ Copy and paste the schema you want to use for the value, save and close the file to continue" @@ -17954,21 +17895,7 @@ EOF playground state set run.test_file "$repro_dir/$repro_test_filename" playground state set run.connector_type "$(get_connector_type | tr -d '\n')" - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening ${repro_test_filename} using configured editor $editor" - $editor $repro_dir/$repro_test_filename - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${repro_test_filename} with code (default) - you can change editor by using playground config editor " - code $repro_dir/$repro_test_filename - fi - fi + open_file_with_editor "$repro_dir/$repro_test_filename" increment_cli_metric nb_reproduction_models log "👷 Number of repro models created so far: $(get_cli_metric nb_reproduction_models)" @@ -19255,21 +19182,7 @@ playground_debug_thread_dump_command() { docker exec $container jstack 1 > "$filename" 2>&1 if [ $? -eq 0 ] then - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening ${filename} using configured editor $editor" - $editor ${filename} - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${filename} with code (default) - you can change editor by using playground config editor " - code ${filename} - fi - fi + open_file_with_editor "${filename}" else logerror "❌ Failed to take thread dump" fi @@ -19777,23 +19690,9 @@ playground_container_logs_command() { docker container logs "$container" > "$filename" 2>&1 if [ $? -eq 0 ] then - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening ${filename} using configured editor $editor" - $editor ${filename} - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${filename} with code (default) - you can change editor by using playground config editor " - code ${filename} - fi - fi + open_file_with_editor "${filename}" else - logerror "Failed to get logs using container logs $container" + logerror "❌ failed to get logs using container logs $container" fi elif [[ -n "$log" ]] then @@ -22886,7 +22785,7 @@ playground_connector_offsets_alter_command() { else if [[ $(type code 2>&1) =~ "not found" ]] then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " + logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" exit 1 else log "✨ Update the connector offsets as per your needs, save and close the file to continue" @@ -22920,7 +22819,7 @@ playground_connector_offsets_alter_command() { else if [[ $(type code 2>&1) =~ "not found" ]] then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " + logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" exit 1 else log "✨ Update the connector offsets as per your needs, save and close the file to continue" @@ -23041,7 +22940,7 @@ playground_connector_offsets_alter_command() { else if [[ $(type code 2>&1) =~ "not found" ]] then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " + logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" exit 1 else log "✨ Update the connector offsets as per your needs, save and close the file to continue" @@ -24138,21 +24037,7 @@ playground_connector_show_config_parameters_command() { echo "🔩 list of all available parameters for connector $connector ($class) and version $version (with default value when applicable)" >> $filename fi - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening ${filename} using configured editor $editor" - $editor ${filename} - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${filename} with code (default) - you can change editor by using playground config editor " - code ${filename} - fi - fi + open_file_with_editor "${filename}" else if [[ -n "$only_show_json" ]] || [[ -n "$only_show_json_file_path" ]] then @@ -25136,7 +25021,7 @@ playground_connector_update_command() { else if [[ $(type code 2>&1) =~ "not found" ]] then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " + logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" exit 1 else log "✨ Update the connector config as per your needs, save and close the file to continue" diff --git a/scripts/cli/src/commands/connector/offsets/alter.sh b/scripts/cli/src/commands/connector/offsets/alter.sh index e24a374d4a..20e2aaddc2 100644 --- a/scripts/cli/src/commands/connector/offsets/alter.sh +++ b/scripts/cli/src/commands/connector/offsets/alter.sh @@ -79,7 +79,7 @@ function handle_first_class_offset() { else if [[ $(type code 2>&1) =~ "not found" ]] then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " + logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" exit 1 else log "✨ Update the connector offsets as per your needs, save and close the file to continue" @@ -113,7 +113,7 @@ function handle_first_class_offset() { else if [[ $(type code 2>&1) =~ "not found" ]] then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " + logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" exit 1 else log "✨ Update the connector offsets as per your needs, save and close the file to continue" @@ -238,7 +238,7 @@ do else if [[ $(type code 2>&1) =~ "not found" ]] then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " + logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" exit 1 else log "✨ Update the connector offsets as per your needs, save and close the file to continue" diff --git a/scripts/cli/src/commands/connector/show-config-parameters.sh b/scripts/cli/src/commands/connector/show-config-parameters.sh index 84babb458d..a5478b2570 100644 --- a/scripts/cli/src/commands/connector/show-config-parameters.sh +++ b/scripts/cli/src/commands/connector/show-config-parameters.sh @@ -202,21 +202,7 @@ do echo "🔩 list of all available parameters for connector $connector ($class) and version $version (with default value when applicable)" >> $filename fi - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening ${filename} using configured editor $editor" - $editor ${filename} - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${filename} with code (default) - you can change editor by using playground config editor " - code ${filename} - fi - fi + open_file_with_editor "${filename}" else if [[ -n "$only_show_json" ]] || [[ -n "$only_show_json_file_path" ]] then diff --git a/scripts/cli/src/commands/connector/update.sh b/scripts/cli/src/commands/connector/update.sh index 2f26949691..9f215a5e0f 100644 --- a/scripts/cli/src/commands/connector/update.sh +++ b/scripts/cli/src/commands/connector/update.sh @@ -80,7 +80,7 @@ do else if [[ $(type code 2>&1) =~ "not found" ]] then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " + logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" exit 1 else log "✨ Update the connector config as per your needs, save and close the file to continue" diff --git a/scripts/cli/src/commands/container/logs.sh b/scripts/cli/src/commands/container/logs.sh index c478c6dbc9..1f0c556ce7 100644 --- a/scripts/cli/src/commands/container/logs.sh +++ b/scripts/cli/src/commands/container/logs.sh @@ -9,23 +9,9 @@ then docker container logs "$container" > "$filename" 2>&1 if [ $? -eq 0 ] then - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening ${filename} using configured editor $editor" - $editor ${filename} - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${filename} with code (default) - you can change editor by using playground config editor " - code ${filename} - fi - fi + open_file_with_editor "${filename}" else - logerror "Failed to get logs using container logs $container" + logerror "❌ failed to get logs using container logs $container" fi elif [[ -n "$log" ]] then diff --git a/scripts/cli/src/commands/debug/thread-dump.sh b/scripts/cli/src/commands/debug/thread-dump.sh index 8ec3debadc..0b39a45cd8 100644 --- a/scripts/cli/src/commands/debug/thread-dump.sh +++ b/scripts/cli/src/commands/debug/thread-dump.sh @@ -13,21 +13,7 @@ log "🎯 Taking thread dump on container ${container} for pid 1" docker exec $container jstack 1 > "$filename" 2>&1 if [ $? -eq 0 ] then - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening ${filename} using configured editor $editor" - $editor ${filename} - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${filename} with code (default) - you can change editor by using playground config editor " - code ${filename} - fi - fi + open_file_with_editor "${filename}" else logerror "❌ Failed to take thread dump" fi \ No newline at end of file diff --git a/scripts/cli/src/commands/open.sh b/scripts/cli/src/commands/open.sh index 7583184926..346b1a2cb2 100644 --- a/scripts/cli/src/commands/open.sh +++ b/scripts/cli/src/commands/open.sh @@ -16,18 +16,4 @@ else fi fi -editor=$(playground config get editor) -if [ "$editor" != "" ] -then - log "📖 Opening ${test_file} using configured editor $editor" - $editor ${test_file} -else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${test_file} with code (default) - you can change editor by using playground config editor " - code ${test_file} - fi -fi \ No newline at end of file +open_file_with_editor "${test_file}" \ No newline at end of file diff --git a/scripts/cli/src/commands/repro/bootstrap.sh b/scripts/cli/src/commands/repro/bootstrap.sh index f27e051dae..ac1a5b4d6e 100644 --- a/scripts/cli/src/commands/repro/bootstrap.sh +++ b/scripts/cli/src/commands/repro/bootstrap.sh @@ -478,7 +478,7 @@ then else if [[ $(type code 2>&1) =~ "not found" ]] then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " + logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" exit 1 else log "✨ Copy and paste the schema you want to use for the key, save and close the file to continue" @@ -561,7 +561,6 @@ then #### schema_file_value if [[ -n "$schema_file_value" ]] then - editor=$(playground config get editor) if [ "$editor" != "" ] then @@ -575,7 +574,7 @@ then else if [[ $(type code 2>&1) =~ "not found" ]] then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " + logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" exit 1 else log "✨ Copy and paste the schema you want to use for the value, save and close the file to continue" @@ -1297,21 +1296,7 @@ fi playground state set run.test_file "$repro_dir/$repro_test_filename" playground state set run.connector_type "$(get_connector_type | tr -d '\n')" -editor=$(playground config get editor) -if [ "$editor" != "" ] -then - log "📖 Opening ${repro_test_filename} using configured editor $editor" - $editor $repro_dir/$repro_test_filename -else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${repro_test_filename} with code (default) - you can change editor by using playground config editor " - code $repro_dir/$repro_test_filename - fi -fi +open_file_with_editor "$repro_dir/$repro_test_filename" increment_cli_metric nb_reproduction_models log "👷 Number of repro models created so far: $(get_cli_metric nb_reproduction_models)" diff --git a/scripts/cli/src/commands/run.sh b/scripts/cli/src/commands/run.sh index dac019f8df..b46fde97ad 100644 --- a/scripts/cli/src/commands/run.sh +++ b/scripts/cli/src/commands/run.sh @@ -415,23 +415,8 @@ fi if [[ -n "$open" ]] then - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening ${test_file} using configured editor $editor" - $editor ${test_file} - check_if_continue - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${test_file} with code (default) - you can change editor by using playground config editor " - code ${test_file} - check_if_continue - fi - fi + open_file_with_editor "${test_file}" + check_if_continue fi if [ $interactive_mode == 1 ] @@ -971,21 +956,7 @@ then if [[ $res == *"$MENU_OPEN_FILE"* ]] then - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening ${test_file} using configured editor $editor" - $editor ${test_file} - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${test_file} with code (default) - you can change editor by using playground config editor " - code ${test_file} - fi - fi + open_file_with_editor "${test_file}" fi if [[ $res == *"$MENU_OPEN_DOCS"* ]] diff --git a/scripts/cli/src/commands/update-version.sh b/scripts/cli/src/commands/update-version.sh index 8a2e6b3882..e66ac7be6f 100644 --- a/scripts/cli/src/commands/update-version.sh +++ b/scripts/cli/src/commands/update-version.sh @@ -257,21 +257,7 @@ then if [[ $res == *"$MENU_OPEN_FILE"* ]] then - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening ${test_file} using configured editor $editor" - $editor ${test_file} - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening ${test_file} with code (default) - you can change editor by using playground config editor " - code ${test_file} - fi - fi + open_file_with_editor "${test_file}" fi if [[ $res == *"$MENU_OPEN_DOCS"* ]] diff --git a/scripts/cli/src/lib/cli_function.sh b/scripts/cli/src/lib/cli_function.sh index 19683fb235..4e21a4e57f 100644 --- a/scripts/cli/src/lib/cli_function.sh +++ b/scripts/cli/src/lib/cli_function.sh @@ -1568,3 +1568,16 @@ function check_for_ec2_instance_running() { done fi } + +function open_file_with_editor() { + filename="$1" + editor=$(playground config get editor) + if [ "$editor" != "" ] && command -v "$editor" > /dev/null + then + log "📖 opening ${filename} using configured editor \"$editor\" (you can change editor by using \"playground config set editor \")" + $editor ${filename} + else + logerror "❌ editor \"$editor\" is not installed - you can change editor by using \"playground config set editor \"" + exit 1 + fi +} \ No newline at end of file diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 06c16c65b5..e314b02c73 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -1157,21 +1157,7 @@ done if [[ -n "$open" ]] then - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "📖 Opening /tmp/jmx_metrics.log using configured editor $editor" - $editor /tmp/jmx_metrics.log - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found - you can change editor by using playground config editor " - exit 1 - else - log "📖 Opening /tmp/jmx_metrics.log with code (default) - you can change editor by using playground config editor " - code /tmp/jmx_metrics.log - fi - fi + open_file_with_editor "/tmp/jmx_metrics.log" fi } From e6c976ab832ee86341350b19d8bc51dbcc2b3301 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 22 Jan 2025 20:38:59 +0100 Subject: [PATCH 183/659] open_file_with_editor --wait --- scripts/cli/playground | 142 +++--------------- .../src/commands/connector/offsets/alter.sh | 66 +------- scripts/cli/src/commands/connector/update.sh | 23 +-- scripts/cli/src/commands/repro/bootstrap.sh | 48 +----- scripts/cli/src/lib/cli_function.sh | 9 +- 5 files changed, 41 insertions(+), 247 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index fc1fa5fb0c..f18fd50bf7 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -7983,11 +7983,18 @@ function check_for_ec2_instance_running() { function open_file_with_editor() { filename="$1" + wait="$2" + editor=$(playground config get editor) if [ "$editor" != "" ] && command -v "$editor" > /dev/null then log "📖 opening ${filename} using configured editor \"$editor\" (you can change editor by using \"playground config set editor \")" - $editor ${filename} + if [ "$editor" = "code" ] && [ "$wait" != "" ] + then + code --wait ${filename} + else + $editor ${filename} + fi else logerror "❌ editor \"$editor\" is not installed - you can change editor by using \"playground config set editor \"" exit 1 @@ -17068,27 +17075,9 @@ playground_repro_bootstrap_command() { if [[ -n "$schema_file_key" ]] then + log "✨ Copy and paste the schema you want to use for the key, save and close the file to continue" + open_file_with_editor "$tmp_dir/key_schema" "--wait" - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "✨ Copy and paste the schema you want to use for the key, save and close the file to continue" - if [ "$editor" = "code" ] - then - code --wait $tmp_dir/key_schema - else - $editor $tmp_dir/key_schema - fi - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" - exit 1 - else - log "✨ Copy and paste the schema you want to use for the key, save and close the file to continue" - code --wait $tmp_dir/key_schema - fi - fi case "${producer}" in avro-with-key) original_namespace=$(cat $tmp_dir/key_schema | jq -r .namespace) @@ -17163,26 +17152,8 @@ playground_repro_bootstrap_command() { if [[ -n "$schema_file_value" ]] then - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "✨ Copy and paste the schema you want to use for the value, save and close the file to continue" - if [ "$editor" = "code" ] - then - code --wait $tmp_dir/value_schema - else - $editor $tmp_dir/value_schema - fi - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" - exit 1 - else - log "✨ Copy and paste the schema you want to use for the value, save and close the file to continue" - code --wait $tmp_dir/value_schema - fi - fi + log "✨ Copy and paste the schema you want to use for the value, save and close the file to continue" + open_file_with_editor "$tmp_dir/value_schema" "--wait" case "${producer}" in avro|avro-with-key) @@ -22772,26 +22743,8 @@ playground_connector_offsets_alter_command() { jq 'del(.metadata)' $file > $file_tmp cp $file_tmp $file - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "✨ Update the connector offsets as per your needs, save and close the file to continue" - if [ "$editor" = "code" ] - then - code --wait $file - else - $editor $file - fi - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" - exit 1 - else - log "✨ Update the connector offsets as per your needs, save and close the file to continue" - code --wait $file - fi - fi + log "✨ Update the connector offsets as per your needs, save and close the file to continue" + open_file_with_editor "${file}" "--wait" handle_ccloud_connect_rest_api "curl -s --request POST -H \"Content-Type: application/json\" --data @$file \"https://api.confluent.cloud/connect/v1/environments/$environment/clusters/$cluster/connectors/$connector/offsets/request\" --header \"authorization: Basic $authorization\"" else @@ -22806,26 +22759,8 @@ playground_connector_offsets_alter_command() { file=$tmp_dir/offsets-$connector.json echo "$curl_output" | jq . > $file - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "✨ Update the connector offsets as per your needs, save and close the file to continue" - if [ "$editor" = "code" ] - then - code --wait $file - else - $editor $file - fi - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" - exit 1 - else - log "✨ Update the connector offsets as per your needs, save and close the file to continue" - code --wait $file - fi - fi + log "✨ Update the connector offsets as per your needs, save and close the file to continue" + open_file_with_editor "${file}" "--wait" playground connector stop --connector $connector @@ -22927,26 +22862,8 @@ playground_connector_offsets_alter_command() { echo "topic,partition,current-offset" > $file docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector $security --export --reset-offsets --to-current --all-topics --dry-run >> $file - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "✨ Update the connector offsets as per your needs, save and close the file to continue" - if [ "$editor" = "code" ] - then - code --wait $file - else - $editor $file - fi - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" - exit 1 - else - log "✨ Update the connector offsets as per your needs, save and close the file to continue" - code --wait $file - fi - fi + log "✨ Update the connector offsets as per your needs, save and close the file to continue" + open_file_with_editor "${file}" "--wait" # remove any empty lines and header grep -v '^$' "$file" > $tmp_dir/tmp && mv $tmp_dir/tmp "$file" @@ -25008,27 +24925,8 @@ playground_connector_update_command() { echo -e "" >> $file playground connector show-config-parameters --connector $connector | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" >> $file - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "✨ Update the connector config as per your needs, save and close the file to continue" - if [ "$editor" = "code" ] - then - code --wait $file - else - $editor $file - fi - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" - exit 1 - else - log "✨ Update the connector config as per your needs, save and close the file to continue" - code --wait $file - fi - fi - + log "✨ Update the connector config as per your needs, save and close the file to continue" + open_file_with_editor "${file}" "--wait" bash $file done diff --git a/scripts/cli/src/commands/connector/offsets/alter.sh b/scripts/cli/src/commands/connector/offsets/alter.sh index 20e2aaddc2..cc2cb5fb71 100644 --- a/scripts/cli/src/commands/connector/offsets/alter.sh +++ b/scripts/cli/src/commands/connector/offsets/alter.sh @@ -66,26 +66,8 @@ function handle_first_class_offset() { jq 'del(.metadata)' $file > $file_tmp cp $file_tmp $file - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "✨ Update the connector offsets as per your needs, save and close the file to continue" - if [ "$editor" = "code" ] - then - code --wait $file - else - $editor $file - fi - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" - exit 1 - else - log "✨ Update the connector offsets as per your needs, save and close the file to continue" - code --wait $file - fi - fi + log "✨ Update the connector offsets as per your needs, save and close the file to continue" + open_file_with_editor "${file}" "--wait" handle_ccloud_connect_rest_api "curl -s --request POST -H \"Content-Type: application/json\" --data @$file \"https://api.confluent.cloud/connect/v1/environments/$environment/clusters/$cluster/connectors/$connector/offsets/request\" --header \"authorization: Basic $authorization\"" else @@ -100,26 +82,8 @@ function handle_first_class_offset() { file=$tmp_dir/offsets-$connector.json echo "$curl_output" | jq . > $file - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "✨ Update the connector offsets as per your needs, save and close the file to continue" - if [ "$editor" = "code" ] - then - code --wait $file - else - $editor $file - fi - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" - exit 1 - else - log "✨ Update the connector offsets as per your needs, save and close the file to continue" - code --wait $file - fi - fi + log "✨ Update the connector offsets as per your needs, save and close the file to continue" + open_file_with_editor "${file}" "--wait" playground connector stop --connector $connector @@ -225,26 +189,8 @@ do echo "topic,partition,current-offset" > $file docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector $security --export --reset-offsets --to-current --all-topics --dry-run >> $file - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "✨ Update the connector offsets as per your needs, save and close the file to continue" - if [ "$editor" = "code" ] - then - code --wait $file - else - $editor $file - fi - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" - exit 1 - else - log "✨ Update the connector offsets as per your needs, save and close the file to continue" - code --wait $file - fi - fi + log "✨ Update the connector offsets as per your needs, save and close the file to continue" + open_file_with_editor "${file}" "--wait" # remove any empty lines and header grep -v '^$' "$file" > $tmp_dir/tmp && mv $tmp_dir/tmp "$file" diff --git a/scripts/cli/src/commands/connector/update.sh b/scripts/cli/src/commands/connector/update.sh index 9f215a5e0f..01348091f4 100644 --- a/scripts/cli/src/commands/connector/update.sh +++ b/scripts/cli/src/commands/connector/update.sh @@ -67,26 +67,7 @@ do echo -e "" >> $file playground connector show-config-parameters --connector $connector | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" >> $file - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "✨ Update the connector config as per your needs, save and close the file to continue" - if [ "$editor" = "code" ] - then - code --wait $file - else - $editor $file - fi - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" - exit 1 - else - log "✨ Update the connector config as per your needs, save and close the file to continue" - code --wait $file - fi - fi - + log "✨ Update the connector config as per your needs, save and close the file to continue" + open_file_with_editor "${file}" "--wait" bash $file done diff --git a/scripts/cli/src/commands/repro/bootstrap.sh b/scripts/cli/src/commands/repro/bootstrap.sh index ac1a5b4d6e..1de03a8535 100644 --- a/scripts/cli/src/commands/repro/bootstrap.sh +++ b/scripts/cli/src/commands/repro/bootstrap.sh @@ -462,29 +462,9 @@ then #### schema_file_key if [[ -n "$schema_file_key" ]] then + log "✨ Copy and paste the schema you want to use for the key, save and close the file to continue" + open_file_with_editor "$tmp_dir/key_schema" "--wait" - - - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "✨ Copy and paste the schema you want to use for the key, save and close the file to continue" - if [ "$editor" = "code" ] - then - code --wait $tmp_dir/key_schema - else - $editor $tmp_dir/key_schema - fi - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" - exit 1 - else - log "✨ Copy and paste the schema you want to use for the key, save and close the file to continue" - code --wait $tmp_dir/key_schema - fi - fi case "${producer}" in avro-with-key) original_namespace=$(cat $tmp_dir/key_schema | jq -r .namespace) @@ -561,27 +541,9 @@ then #### schema_file_value if [[ -n "$schema_file_value" ]] then - editor=$(playground config get editor) - if [ "$editor" != "" ] - then - log "✨ Copy and paste the schema you want to use for the value, save and close the file to continue" - if [ "$editor" = "code" ] - then - code --wait $tmp_dir/value_schema - else - $editor $tmp_dir/value_schema - fi - else - if [[ $(type code 2>&1) =~ "not found" ]] - then - logerror "Could not determine an editor to use as default code is not found (you can change editor by using \"playground config set editor \")" - exit 1 - else - log "✨ Copy and paste the schema you want to use for the value, save and close the file to continue" - code --wait $tmp_dir/value_schema - fi - fi - + log "✨ Copy and paste the schema you want to use for the value, save and close the file to continue" + open_file_with_editor "$tmp_dir/value_schema" "--wait" + case "${producer}" in avro|avro-with-key) original_namespace=$(cat $tmp_dir/value_schema | jq -r .namespace) diff --git a/scripts/cli/src/lib/cli_function.sh b/scripts/cli/src/lib/cli_function.sh index 4e21a4e57f..ac1316f9b0 100644 --- a/scripts/cli/src/lib/cli_function.sh +++ b/scripts/cli/src/lib/cli_function.sh @@ -1571,11 +1571,18 @@ function check_for_ec2_instance_running() { function open_file_with_editor() { filename="$1" + wait="$2" + editor=$(playground config get editor) if [ "$editor" != "" ] && command -v "$editor" > /dev/null then log "📖 opening ${filename} using configured editor \"$editor\" (you can change editor by using \"playground config set editor \")" - $editor ${filename} + if [ "$editor" = "code" ] && [ "$wait" != "" ] + then + code --wait ${filename} + else + $editor ${filename} + fi else logerror "❌ editor \"$editor\" is not installed - you can change editor by using \"playground config set editor \"" exit 1 From 1c7f6cb5bdcb1910176be64facc3a82cbda6748f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 22 Jan 2025 20:57:36 +0100 Subject: [PATCH 184/659] check for open command --- scripts/cli/playground | 36 +++++++++++++------ .../open-ccloud-connector-in-browser.sh | 16 ++++++--- .../cli/src/commands/connector/open-docs.sh | 2 +- scripts/cli/src/commands/open-docs.sh | 2 +- scripts/cli/src/commands/tcp-proxy/start.sh | 9 +++-- scripts/cli/src/commands/topic/consume.sh | 7 +++- 6 files changed, 50 insertions(+), 22 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index f18fd50bf7..6fbdb4399d 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -16117,7 +16117,7 @@ playground_open_docs_command() { if [[ $url =~ "http" ]] then short_url=$(echo $url | cut -d '#' -f 1) - if [[ -n "$only_show_url" ]] + if [[ -n "$only_show_url" ]] || [[ $(type -f open 2>&1) =~ "not found" ]] then log "🌐 documentation is available at:" echo "$short_url" @@ -18608,9 +18608,12 @@ EOF log "💗 you can now use zazkia tcp proxy using " log "🌐 zazkia UI is available on http://localhost:9191" - set +e - open "http://localhost:9191" - set -e + if [[ $(type -f open 2>&1) =~ "not found" ]] + then + : + else + open "http://localhost:9191" + fi if [[ -n "$skip_automatic_connector_config" ]] then @@ -20600,7 +20603,12 @@ playground_topic_consume_command() { plot 'latency.csv' using 1:(\$2-\$3) with points;" # open $latency_csv - open $latency_png + if [[ $(type -f open 2>&1) =~ "not found" ]] + then + : + else + open $latency_png + fi fi } @@ -24275,7 +24283,7 @@ playground_connector_open_docs_command() { if [[ $url =~ "http" ]] then short_url=$(echo $url | cut -d '#' -f 1) - if [[ -n "$only_show_url" ]] + if [[ -n "$only_show_url" ]] || [[ $(type -f open 2>&1) =~ "not found" ]] then log "🌐 documentation for $connector_type connector $name is available at:" echo "$short_url" @@ -24491,13 +24499,19 @@ playground_connector_open_ccloud_connector_in_browser_command() { TYPE="sources" fi - if [[ -n "$browser" ]] + if [[ $(type -f open 2>&1) =~ "not found" ]] then - log "🤖 Open $connector_type connector $connector ($connectorId) in Confluent Cloud dashboard with browser $browser" - open -a "$browser" "https://confluent.cloud/environments/$environment/clusters/$cluster/connectors/$TYPE/$connector?granularity=PT1M&interval=3600000&label=Last%20hour" + log "🔗 Cannot open browser, use url:" + echo "https://confluent.cloud/environments/$environment/clusters/$cluster/connectors/$TYPE/$connector?granularity=PT1M&interval=3600000&label=Last%20hour" else - log "🤖 Open $connector_type connector $connector ($connectorId) in Confluent Cloud dashboard" - open "https://confluent.cloud/environments/$environment/clusters/$cluster/connectors/$TYPE/$connector?granularity=PT1M&interval=3600000&label=Last%20hour" + if [[ -n "$browser" ]] + then + log "🤖 Open $connector_type connector $connector ($connectorId) in Confluent Cloud dashboard with browser $browser" + open -a "$browser" "https://confluent.cloud/environments/$environment/clusters/$cluster/connectors/$TYPE/$connector?granularity=PT1M&interval=3600000&label=Last%20hour" + else + log "🤖 Open $connector_type connector $connector ($connectorId) in Confluent Cloud dashboard" + open "https://confluent.cloud/environments/$environment/clusters/$cluster/connectors/$TYPE/$connector?granularity=PT1M&interval=3600000&label=Last%20hour" + fi fi done } diff --git a/scripts/cli/src/commands/connector/open-ccloud-connector-in-browser.sh b/scripts/cli/src/commands/connector/open-ccloud-connector-in-browser.sh index 88301fc0e9..df25629e97 100644 --- a/scripts/cli/src/commands/connector/open-ccloud-connector-in-browser.sh +++ b/scripts/cli/src/commands/connector/open-ccloud-connector-in-browser.sh @@ -41,12 +41,18 @@ do TYPE="sources" fi - if [[ -n "$browser" ]] + if [[ $(type -f open 2>&1) =~ "not found" ]] then - log "🤖 Open $connector_type connector $connector ($connectorId) in Confluent Cloud dashboard with browser $browser" - open -a "$browser" "https://confluent.cloud/environments/$environment/clusters/$cluster/connectors/$TYPE/$connector?granularity=PT1M&interval=3600000&label=Last%20hour" + log "🔗 Cannot open browser, use url:" + echo "https://confluent.cloud/environments/$environment/clusters/$cluster/connectors/$TYPE/$connector?granularity=PT1M&interval=3600000&label=Last%20hour" else - log "🤖 Open $connector_type connector $connector ($connectorId) in Confluent Cloud dashboard" - open "https://confluent.cloud/environments/$environment/clusters/$cluster/connectors/$TYPE/$connector?granularity=PT1M&interval=3600000&label=Last%20hour" + if [[ -n "$browser" ]] + then + log "🤖 Open $connector_type connector $connector ($connectorId) in Confluent Cloud dashboard with browser $browser" + open -a "$browser" "https://confluent.cloud/environments/$environment/clusters/$cluster/connectors/$TYPE/$connector?granularity=PT1M&interval=3600000&label=Last%20hour" + else + log "🤖 Open $connector_type connector $connector ($connectorId) in Confluent Cloud dashboard" + open "https://confluent.cloud/environments/$environment/clusters/$cluster/connectors/$TYPE/$connector?granularity=PT1M&interval=3600000&label=Last%20hour" + fi fi done \ No newline at end of file diff --git a/scripts/cli/src/commands/connector/open-docs.sh b/scripts/cli/src/commands/connector/open-docs.sh index 453d9f46c9..993f38ffc3 100644 --- a/scripts/cli/src/commands/connector/open-docs.sh +++ b/scripts/cli/src/commands/connector/open-docs.sh @@ -37,7 +37,7 @@ else if [[ $url =~ "http" ]] then short_url=$(echo $url | cut -d '#' -f 1) - if [[ -n "$only_show_url" ]] + if [[ -n "$only_show_url" ]] || [[ $(type -f open 2>&1) =~ "not found" ]] then log "🌐 documentation for $connector_type connector $name is available at:" echo "$short_url" diff --git a/scripts/cli/src/commands/open-docs.sh b/scripts/cli/src/commands/open-docs.sh index ee519e073e..9ebe837e72 100644 --- a/scripts/cli/src/commands/open-docs.sh +++ b/scripts/cli/src/commands/open-docs.sh @@ -21,7 +21,7 @@ url=${url//)/} if [[ $url =~ "http" ]] then short_url=$(echo $url | cut -d '#' -f 1) - if [[ -n "$only_show_url" ]] + if [[ -n "$only_show_url" ]] || [[ $(type -f open 2>&1) =~ "not found" ]] then log "🌐 documentation is available at:" echo "$short_url" diff --git a/scripts/cli/src/commands/tcp-proxy/start.sh b/scripts/cli/src/commands/tcp-proxy/start.sh index 4c1043764b..4e061ed728 100644 --- a/scripts/cli/src/commands/tcp-proxy/start.sh +++ b/scripts/cli/src/commands/tcp-proxy/start.sh @@ -70,9 +70,12 @@ bash /tmp/playground-command-zazkia log "💗 you can now use zazkia tcp proxy using " log "🌐 zazkia UI is available on http://localhost:9191" -set +e -open "http://localhost:9191" -set -e +if [[ $(type -f open 2>&1) =~ "not found" ]] +then + : +else + open "http://localhost:9191" +fi if [[ -n "$skip_automatic_connector_config" ]] then diff --git a/scripts/cli/src/commands/topic/consume.sh b/scripts/cli/src/commands/topic/consume.sh index 9ad92f780a..e6c9dbdfe1 100644 --- a/scripts/cli/src/commands/topic/consume.sh +++ b/scripts/cli/src/commands/topic/consume.sh @@ -510,5 +510,10 @@ then plot 'latency.csv' using 1:(\$2-\$3) with points;" # open $latency_csv - open $latency_png + if [[ $(type -f open 2>&1) =~ "not found" ]] + then + : + else + open $latency_png + fi fi \ No newline at end of file From 36d02afa46c52a13764f3a53092ae6539f30557c Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 28 Jan 2025 10:10:07 +0100 Subject: [PATCH 185/659] remove env variables --- ...ntext.backup-and-restore.with-assuming-iam-role-config.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/connect/connect-aws-s3-source/docker-compose.plaintext.backup-and-restore.with-assuming-iam-role-config.yml b/connect/connect-aws-s3-source/docker-compose.plaintext.backup-and-restore.with-assuming-iam-role-config.yml index bde4a52352..69f7ee4a86 100644 --- a/connect/connect-aws-s3-source/docker-compose.plaintext.backup-and-restore.with-assuming-iam-role-config.yml +++ b/connect/connect-aws-s3-source/docker-compose.plaintext.backup-and-restore.with-assuming-iam-role-config.yml @@ -3,6 +3,4 @@ services: connect: environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-s3-source,/usr/share/confluent-hub-components/confluentinc-kafka-connect-s3 - AWS_REGION: $AWS_REGION - AWS_ACCESS_KEY_ID: $AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID - AWS_SECRET_ACCESS_KEY: $AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY \ No newline at end of file + AWS_REGION: $AWS_REGION \ No newline at end of file From 4c07caefc1e6901809598fb8dccec25d8cfd4124 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 28 Jan 2025 10:26:43 +0100 Subject: [PATCH 186/659] s3.credentials.provider.aws.access.key.id --- ...d-restore-with-assuming-iam-role-config.sh | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role-config.sh b/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role-config.sh index dd9a6c550d..aa4c5028ef 100755 --- a/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role-config.sh +++ b/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role-config.sh @@ -109,24 +109,26 @@ rm -f s3_topic+0+0000000000.avro log "Creating Backup and Restore S3 Source connector with bucket name <$AWS_BUCKET_NAME>" playground connector create-or-update --connector s3-source << EOF { - "tasks.max": "1", - "connector.class": "io.confluent.connect.s3.source.S3SourceConnector", - "s3.region": "$AWS_REGION", - "s3.bucket.name": "$AWS_BUCKET_NAME", - "topics.dir": "$TAG", - "format.class": "io.confluent.connect.s3.format.avro.AvroFormat", - "confluent.license": "", - "confluent.topic.bootstrap.servers": "broker:9092", - "confluent.topic.replication.factor": "1", - "s3.credentials.provider.class": "io.confluent.connect.s3.auth.AwsAssumeRoleCredentialsProvider", - "s3.credentials.provider.sts.role.arn": "$AWS_STS_ROLE_ARN", - "s3.credentials.provider.sts.role.session.name": "session-name", - "s3.credentials.provider.sts.role.external.id": "123", - "transforms": "AddPrefix", - "transforms.AddPrefix.type": "org.apache.kafka.connect.transforms.RegexRouter", - "transforms.AddPrefix.regex": ".*", - "transforms.AddPrefix.replacement": "copy_of_\$0" - } + "tasks.max": "1", + "connector.class": "io.confluent.connect.s3.source.S3SourceConnector", + "s3.region": "$AWS_REGION", + "s3.bucket.name": "$AWS_BUCKET_NAME", + "topics.dir": "$TAG", + "format.class": "io.confluent.connect.s3.format.avro.AvroFormat", + "confluent.license": "", + "confluent.topic.bootstrap.servers": "broker:9092", + "confluent.topic.replication.factor": "1", + "s3.credentials.provider.class": "io.confluent.connect.s3.auth.AwsAssumeRoleCredentialsProvider", + "s3.credentials.provider.sts.role.arn": "$AWS_STS_ROLE_ARN", + "s3.credentials.provider.sts.role.session.name": "session-name", + "s3.credentials.provider.sts.role.external.id": "123", + "s3.credentials.provider.aws.access.key.id": "$AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID", + "s3.credentials.provider.aws.secret.access.key": "$AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY", + "transforms": "AddPrefix", + "transforms.AddPrefix.type": "org.apache.kafka.connect.transforms.RegexRouter", + "transforms.AddPrefix.regex": ".*", + "transforms.AddPrefix.replacement": "copy_of_\$0" +} EOF sleep 10 From accae9024f4221b8824cd94d2812055684e06da2 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 28 Jan 2025 12:25:57 +0100 Subject: [PATCH 187/659] =?UTF-8?q?=F0=9F=A7=B9Use=20REST=20API=20readines?= =?UTF-8?q?s=20for=20waiting=20connect=20to=20start=20#6226?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 166 +++++++++++++++--- scripts/cli/src/bashly.yml | 13 ++ .../wait-for-connect-rest-api-ready.sh | 15 ++ scripts/cli/src/lib/utils_function.sh | 16 +- 4 files changed, 181 insertions(+), 29 deletions(-) create mode 100644 scripts/cli/src/commands/container/wait-for-connect-rest-api-ready.sh diff --git a/scripts/cli/playground b/scripts/cli/playground index 6fbdb4399d..37693384b3 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -3800,21 +3800,21 @@ playground_container_usage() { echo # :command.usage_commands printf "%s\n" "$(bold "== Commands ==")" - printf " %s 📝 Get properties file from a container\n" "$(green "get-properties") " + printf " %s 📝 Get properties file from a container\n" "$(green "get-properties") " echo printf "%s\n" "$(bold "Container commands:")" - printf " %s 💫 Recreate container(s)\n" "$(green "recreate") " - printf " %s 🖥️ Get ip address of running containers\n" "$(green "get-ip-addresses") " - printf " %s 💀 Kill all containers\n" "$(green "kill-all") " - printf " %s 🕵️ Tail and follow container logs\n" "$(green "logs") " - printf " %s 🛬 SSH into container\n" "$(green "ssh") " - printf " %s 🤎 Change java JDK version using Azul JDK (https://www.azul.com/downloads/#downloads-table-zulu)\n" "$(green "change-jdk") " - printf " %s 🪄 Execute command in a container\n" "$(green "exec") " - printf " %s 🔁 Restart a container\n" "$(green "restart") " - printf " %s ⏸️ Pause a container\n" "$(green "pause") " - printf " %s ⏯️ Resume a container\n" "$(green "resume") " - printf " %s 🔫 Kill a container\n" "$(green "kill") " - printf " %s 📦 Set environment variable(s) for a container\n" "$(green "set-environment-variables")" + printf " %s 💫 Recreate container(s)\n" "$(green "recreate") " + printf " %s 🖥️ Get ip address of running containers\n" "$(green "get-ip-addresses") " + printf " %s 💀 Kill all containers\n" "$(green "kill-all") " + printf " %s 🕵️ Tail and follow container logs\n" "$(green "logs") " + printf " %s 🛬 SSH into container\n" "$(green "ssh") " + printf " %s 🤎 Change java JDK version using Azul JDK (https://www.azul.com/downloads/#downloads-table-zulu)\n" "$(green "change-jdk") " + printf " %s 🪄 Execute command in a container\n" "$(green "exec") " + printf " %s 🔁 Restart a container\n" "$(green "restart") " + printf " %s ⏸️ Pause a container\n" "$(green "pause") " + printf " %s ⏯️ Resume a container\n" "$(green "resume") " + printf " %s 🔫 Kill a container\n" "$(green "kill") " + printf " %s 📦 Set environment variable(s) for a container\n" "$(green "set-environment-variables") " echo # :command.long_usage @@ -4299,6 +4299,34 @@ playground_container_set_environment_variables_usage() { fi } +# :command.usage +playground_container_wait_for_connect_rest_api_ready_usage() { + printf "playground container wait-for-connect-rest-api-ready - 🚏 wait-for-connect-rest-api-ready\n\n" + + printf "%s\n" "$(bold "== Usage ==")" + printf " playground container wait-for-connect-rest-api-ready [OPTIONS]\n" + printf " playground container wait-for-connect-rest-api-ready --help | -h\n" + echo + + # :command.long_usage + if [[ -n "$long_usage" ]]; then + printf "%s\n" "$(bold "== Options ==")" + + # :command.usage_flags + # :flag.usage + printf " %s\n" "$(magenta "--max-wait MAX_WAIT")" + printf " ⏳ Max time in seconds to wait\n" + printf " %s\n" "Default: 300" + echo + + # :command.usage_fixed_flags + printf " %s\n" "$(magenta "--help, -h")" + printf " Show this help\n" + echo + + fi +} + # :command.usage playground_topic_usage() { printf "playground topic - 🗳 Topic commands\n\n" @@ -9248,7 +9276,7 @@ function wait_container_ready() { playground --output-level WARN container logs --container $CONTROL_CENTER_CONTAINER --wait-for-log "Started NetworkTrafficServerConnector" --max-wait $MAX_WAIT else log "⌛ Waiting up to $MAX_WAIT seconds for ${CONNECT_CONTAINER} to start" - playground --output-level WARN container logs --container $CONNECT_CONTAINER --wait-for-log "Finished starting connectors and tasks" --max-wait $MAX_WAIT + playground container wait-for-connect-rest-api-ready --max-wait $MAX_WAIT fi # Verify Docker containers started if [[ $(docker container ps) =~ "Exit 137" ]] @@ -12267,7 +12295,7 @@ function handle_ccloud_connect_rest_api () { if [ "$curl_output" == "[]" ] then # logerror "No connector running" - # exit 1 + # return 1 echo "" return fi @@ -12283,18 +12311,18 @@ function handle_ccloud_connect_rest_api () { fi logerror "Command failed with error code $code" logerror "$message" - exit 1 + return 1 elif echo "$curl_output" | jq 'has("errors")' 2> /dev/null | grep -q true then code=$(echo "$curl_output" | jq -r '.errors[0].status') message=$(echo "$curl_output" | jq -r '.errors[0].detail') logerror "Command failed with error code $code" logerror "$message" - exit 1 + return 1 fi else logerror "❌ curl request failed with error code $ret!" - exit 1 + return 1 fi } @@ -12312,7 +12340,7 @@ function handle_onprem_connect_rest_api () { if [ "$curl_output" == "[]" ] then # logerror "No connector running" - # exit 1 + # return 1 echo "" return fi @@ -12323,11 +12351,11 @@ function handle_onprem_connect_rest_api () { message=$(echo "$curl_output" | jq -r .message) logerror "Command failed with error code $error_code" logerror "$message" - exit 1 + return 1 fi else logerror "❌ curl request failed with error code $ret!" - exit 1 + return 1 fi } @@ -19843,6 +19871,26 @@ EOF fi } +# :command.function +playground_container_wait_for_connect_rest_api_ready_command() { + # src/commands/container/wait-for-connect-rest-api-ready.sh + max_wait="${args[--max-wait]}" + + get_connect_url_and_security + cur_wait=0 + while ! handle_onprem_connect_rest_api "curl $security -s \"$connect_url\"" > /dev/null; + do + sleep 1 + cur_wait=$(( cur_wait+1 )) + if [[ "$cur_wait" -gt "$max_wait" ]] + then + logerror "The connect REST API is still not ready after $max_wait seconds, see output" + handle_onprem_connect_rest_api "curl $security -s \"$connect_url\"" + return 1 + fi + done +} + # :command.function playground_topic_get_number_records_command() { # src/commands/topic/get-number-records.sh @@ -33970,6 +34018,13 @@ playground_container_parse_requirements() { shift $# ;; + wait-for-connect-rest-api-ready) + action="wait-for-connect-rest-api-ready" + shift + playground_container_wait_for_connect_rest_api_ready_parse_requirements "$@" + shift $# + ;; + # :command.command_fallback "") playground_container_usage >&2 @@ -34963,6 +35018,74 @@ playground_container_set_environment_variables_parse_requirements() { } +# :command.parse_requirements +playground_container_wait_for_connect_rest_api_ready_parse_requirements() { + # :command.fixed_flags_filter + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + --help | -h) + long_usage=yes + playground_container_wait_for_connect_rest_api_ready_usage + exit + ;; + + *) + break + ;; + + esac + done + + # :command.command_filter + action="container wait-for-connect-rest-api-ready" + + # :command.parse_requirements_while + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + # :flag.case + --max-wait) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + args['--max-wait']="$2" + shift + shift + else + printf "%s\n" "--max-wait requires an argument: --max-wait MAX_WAIT" >&2 + exit 1 + fi + ;; + + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; + + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + printf "invalid argument: %s\n" "$key" >&2 + exit 1 + + ;; + + esac + done + + # :command.default_assignments + [[ -n ${args['--max-wait']:-} ]] || args['--max-wait']="300" + + # :command.validations + # :flag.validations + if [[ -v args['--max-wait'] && -n $(validate_integer "${args['--max-wait']:-}") ]]; then + printf "validation error in %s:\n%s\n" "--max-wait MAX_WAIT" "$(validate_integer "${args['--max-wait']:-}")" >&2 + exit 1 + fi + +} + # :command.parse_requirements playground_topic_parse_requirements() { # :command.fixed_flags_filter @@ -39840,6 +39963,7 @@ run() { "container resume") playground_container_resume_command ;; "container kill") playground_container_kill_command ;; "container set-environment-variables") playground_container_set_environment_variables_command ;; + "container wait-for-connect-rest-api-ready") playground_container_wait_for_connect_rest_api_ready_command ;; "topic") playground_topic_command ;; "topic get-number-records") playground_topic_get_number_records_command ;; "topic display-consumer-offsets") playground_topic_display_consumer_offsets_command ;; diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index b5bc85116d..a47e8812fb 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -2112,6 +2112,19 @@ commands: help: |- 🧽 Restore back original values before any changes was made + - name: wait-for-connect-rest-api-ready + group: Container + private: true + help: |- + 🚏 wait-for-connect-rest-api-ready + flags: + - long: --max-wait + arg: max_wait + validate: integer + default: "300" + help: |- + ⏳ Max time in seconds to wait + - name: topic expose: always group: Topic diff --git a/scripts/cli/src/commands/container/wait-for-connect-rest-api-ready.sh b/scripts/cli/src/commands/container/wait-for-connect-rest-api-ready.sh new file mode 100644 index 0000000000..3a3133a128 --- /dev/null +++ b/scripts/cli/src/commands/container/wait-for-connect-rest-api-ready.sh @@ -0,0 +1,15 @@ +max_wait="${args[--max-wait]}" + +get_connect_url_and_security +cur_wait=0 +while ! handle_onprem_connect_rest_api "curl $security -s \"$connect_url\"" > /dev/null; +do + sleep 1 + cur_wait=$(( cur_wait+1 )) + if [[ "$cur_wait" -gt "$max_wait" ]] + then + logerror "❌ the connect REST API is still not ready after $max_wait seconds, see output" + handle_onprem_connect_rest_api "curl $security -s \"$connect_url\"" + return 1 + fi +done \ No newline at end of file diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index e314b02c73..75528e3bf2 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -1050,7 +1050,7 @@ function wait_container_ready() { playground --output-level WARN container logs --container $CONTROL_CENTER_CONTAINER --wait-for-log "Started NetworkTrafficServerConnector" --max-wait $MAX_WAIT else log "⌛ Waiting up to $MAX_WAIT seconds for ${CONNECT_CONTAINER} to start" - playground --output-level WARN container logs --container $CONNECT_CONTAINER --wait-for-log "Finished starting connectors and tasks" --max-wait $MAX_WAIT + playground container wait-for-connect-rest-api-ready --max-wait $MAX_WAIT fi # Verify Docker containers started if [[ $(docker container ps) =~ "Exit 137" ]] @@ -4138,7 +4138,7 @@ function handle_ccloud_connect_rest_api () { if [ "$curl_output" == "[]" ] then # logerror "No connector running" - # exit 1 + # return 1 echo "" return fi @@ -4154,18 +4154,18 @@ function handle_ccloud_connect_rest_api () { fi logerror "Command failed with error code $code" logerror "$message" - exit 1 + return 1 elif echo "$curl_output" | jq 'has("errors")' 2> /dev/null | grep -q true then code=$(echo "$curl_output" | jq -r '.errors[0].status') message=$(echo "$curl_output" | jq -r '.errors[0].detail') logerror "Command failed with error code $code" logerror "$message" - exit 1 + return 1 fi else logerror "❌ curl request failed with error code $ret!" - exit 1 + return 1 fi } @@ -4183,7 +4183,7 @@ function handle_onprem_connect_rest_api () { if [ "$curl_output" == "[]" ] then # logerror "No connector running" - # exit 1 + # return 1 echo "" return fi @@ -4193,11 +4193,11 @@ function handle_onprem_connect_rest_api () { message=$(echo "$curl_output" | jq -r .message) logerror "Command failed with error code $error_code" logerror "$message" - exit 1 + return 1 fi else logerror "❌ curl request failed with error code $ret!" - exit 1 + return 1 fi } From d2bfa30a1f73982e9b40aeae7e1da2a31cb62264 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 28 Jan 2025 12:26:29 +0100 Subject: [PATCH 188/659] wip --- scripts/cli/playground | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 37693384b3..9a6445510f 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -19884,7 +19884,7 @@ playground_container_wait_for_connect_rest_api_ready_command() { cur_wait=$(( cur_wait+1 )) if [[ "$cur_wait" -gt "$max_wait" ]] then - logerror "The connect REST API is still not ready after $max_wait seconds, see output" + logerror "❌ the connect REST API is still not ready after $max_wait seconds, see output" handle_onprem_connect_rest_api "curl $security -s \"$connect_url\"" return 1 fi From eb036a46f33b0597b79f2307218099ab53f147fe Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 28 Jan 2025 13:39:39 +0100 Subject: [PATCH 189/659] 3.5.4 --- connect/connect-iceberg-sink/spark/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connect/connect-iceberg-sink/spark/Dockerfile b/connect/connect-iceberg-sink/spark/Dockerfile index bd8760a55b..88c638cbf6 100644 --- a/connect/connect-iceberg-sink/spark/Dockerfile +++ b/connect/connect-iceberg-sink/spark/Dockerfile @@ -48,7 +48,7 @@ ENV PYTHONPATH=$SPARK_HOME/python:$SPARK_HOME/python/lib/py4j-0.10.9.7-src.zip:$ WORKDIR ${SPARK_HOME} -ENV SPARK_VERSION=3.5.3 +ENV SPARK_VERSION=3.5.4 ENV SPARK_MAJOR_VERSION=3.5 ENV ICEBERG_VERSION=1.5.0 From ea10364e90e0d370e7eb9d44a7fa4849c981a792 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 28 Jan 2025 16:20:00 +0100 Subject: [PATCH 190/659] =?UTF-8?q?=F0=9F=92=AB=20failover=20to=20other=20?= =?UTF-8?q?connect=20worker=20rest=20api=20when=20--enable-multiple-connec?= =?UTF-8?q?t-workers=20is=20used=20#6229?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 21 +++++++++++++++++++-- scripts/cli/src/lib/cli_function.sh | 21 +++++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 9a6445510f..0956eaaeb7 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -6415,11 +6415,28 @@ function get_environment_used() { function get_connect_url_and_security() { get_environment_used - connect_url="http://localhost:8083" + connect_port="8083" + if ! nc -vz localhost 8083 > /dev/null 2>&1 + then + if nc -vz localhost 8283 > /dev/null 2>&1 + then + connect_port="8283" + # log "💫 using connect rest api for connect2 as connect rest api on port 8083 is not available" + elif nc -vz localhost 8383 > /dev/null 2>&1 + then + connect_port="8383" + # log "💫 using connect rest api for connect3 as connect rest api on port 8083 and connect2 rest api on port 8283 are not available" + else + logerror "❌ No available port found for connect rest api" + exit 1 + fi + fi + connect_url="http://localhost:$connect_port" + security="" if [[ "$environment" == "sasl-ssl" ]] || [[ "$environment" == "2way-ssl" ]] then - connect_url="https://localhost:8083" + connect_url="https://localhost:$connect_port" DIR_CLI="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" security="--cert $DIR_CLI/../../environment/$environment/security/connect.certificate.pem --key $DIR_CLI/../../environment/$environment/security/connect.key --tlsv1.2 --cacert $DIR_CLI/../../environment/$environment/security/snakeoil-ca-1.crt" diff --git a/scripts/cli/src/lib/cli_function.sh b/scripts/cli/src/lib/cli_function.sh index ac1316f9b0..453bcd3f97 100644 --- a/scripts/cli/src/lib/cli_function.sh +++ b/scripts/cli/src/lib/cli_function.sh @@ -5,11 +5,28 @@ function get_environment_used() { function get_connect_url_and_security() { get_environment_used - connect_url="http://localhost:8083" + connect_port="8083" + if ! nc -vz localhost 8083 > /dev/null 2>&1 + then + if nc -vz localhost 8283 > /dev/null 2>&1 + then + connect_port="8283" + # log "💫 using connect rest api for connect2 as connect rest api on port 8083 is not available" + elif nc -vz localhost 8383 > /dev/null 2>&1 + then + connect_port="8383" + # log "💫 using connect rest api for connect3 as connect rest api on port 8083 and connect2 rest api on port 8283 are not available" + else + logerror "❌ No available port found for connect rest api" + exit 1 + fi + fi + connect_url="http://localhost:$connect_port" + security="" if [[ "$environment" == "sasl-ssl" ]] || [[ "$environment" == "2way-ssl" ]] then - connect_url="https://localhost:8083" + connect_url="https://localhost:$connect_port" DIR_CLI="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" security="--cert $DIR_CLI/../../environment/$environment/security/connect.certificate.pem --key $DIR_CLI/../../environment/$environment/security/connect.key --tlsv1.2 --cacert $DIR_CLI/../../environment/$environment/security/snakeoil-ca-1.crt" From d972dedee1094fb57bcb047e01db396e9cc71f1d Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 29 Jan 2025 12:00:06 +0100 Subject: [PATCH 191/659] remove error as it works --- .../sqs-source-with-assuming-iam-role.sh | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh b/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh index dd8c01a081..9fb83bc3fc 100755 --- a/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh +++ b/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh @@ -69,35 +69,5 @@ playground connector create-or-update --connector sqs-source << EOF } EOF - -# [2023-07-24 13:18:40,240] ERROR Could not connect to your Amazon SQS queue (io.confluent.connect.sqs.source.SqsSourceConfigValidation:174) -# software.amazon.awssdk.core.exception.SdkClientException: Unable to load credentials from any of the providers in the chain AwsCredentialsProviderChain(credentialsProviders=[SystemPropertyCredentialsProvider(), EnvironmentVariableCredentialsProvider(), WebIdentityTokenCredentialsProvider(), ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(profilesAndSectionsMap=[{default=Profile(name=default, properties=[source_profile, role_arn, role_session_name]), cc-staging-1=Profile(name=cc-staging-1, properties=[output, aws_access_key_id, aws_secret_access_key])}, {}])), ContainerCredentialsProvider(), InstanceProfileCredentialsProvider()]) : [SystemPropertyCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId)., EnvironmentVariableCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId)., WebIdentityTokenCredentialsProvider(): Either the environment variable AWS_WEB_IDENTITY_TOKEN_FILE or the javaproperty aws.webIdentityTokenFile must be set., ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(profilesAndSectionsMap=[{default=Profile(name=default, properties=[source_profile, role_arn, role_session_name]), cc-staging-1=Profile(name=cc-staging-1, properties=[output, aws_access_key_id, aws_secret_access_key])}, {}])): To use assumed roles in the 'default' profile, the 'sts' service module must be on the class path., ContainerCredentialsProvider(): Cannot fetch credentials from container - neither AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variables are set., InstanceProfileCredentialsProvider(): Failed to load credentials from IMDS.] -# at software.amazon.awssdk.core.exception.SdkClientException$BuilderImpl.build(SdkClientException.java:111) -# at software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain.resolveCredentials(AwsCredentialsProviderChain.java:117) -# at software.amazon.awssdk.auth.credentials.internal.LazyAwsCredentialsProvider.resolveCredentials(LazyAwsCredentialsProvider.java:45) -# at software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider.resolveCredentials(DefaultCredentialsProvider.java:128) -# at software.amazon.awssdk.core.internal.util.MetricUtils.measureDuration(MetricUtils.java:50) -# at software.amazon.awssdk.awscore.internal.authcontext.AwsCredentialsAuthorizationStrategy.resolveCredentials(AwsCredentialsAuthorizationStrategy.java:100) -# at software.amazon.awssdk.awscore.internal.authcontext.AwsCredentialsAuthorizationStrategy.addCredentialsToExecutionAttributes(AwsCredentialsAuthorizationStrategy.java:77) -# at software.amazon.awssdk.awscore.internal.AwsExecutionContextBuilder.invokeInterceptorsAndCreateExecutionContext(AwsExecutionContextBuilder.java:123) -# at software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler.invokeInterceptorsAndCreateExecutionContext(AwsAsyncClientHandler.java:65) -# at software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler.lambda$execute$1(BaseAsyncClientHandler.java:77) -# at software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler.measureApiCallSuccess(BaseAsyncClientHandler.java:291) -# at software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler.execute(BaseAsyncClientHandler.java:75) -# at software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler.execute(AwsAsyncClientHandler.java:52) -# at software.amazon.awssdk.services.sqs.DefaultSqsAsyncClient.receiveMessage(DefaultSqsAsyncClient.java:1601) -# at io.confluent.connect.sqs.source.SqsSourceConfigValidation.checkReceiveMessagePermission(SqsSourceConfigValidation.java:120) -# at io.confluent.connect.sqs.source.SqsSourceConfigValidation.performValidation(SqsSourceConfigValidation.java:101) -# at io.confluent.connect.utils.validators.all.ConfigValidation.validate(ConfigValidation.java:185) -# at io.confluent.connect.sqs.source.SqsSourceConnector.validate(SqsSourceConnector.java:80) -# at org.apache.kafka.connect.runtime.AbstractHerder.validateConnectorConfig(AbstractHerder.java:571) -# at org.apache.kafka.connect.runtime.AbstractHerder.lambda$validateConnectorConfig$4(AbstractHerder.java:449) -# at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) -# at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) -# at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) -# at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) -# at java.base/java.lang.Thread.run(Thread.java:829) - - log "Verify we have received the data in test-sqs-source topic" playground topic consume --topic test-sqs-source --min-expected-messages 2 --timeout 60 \ No newline at end of file From 371797cf87e6f16be02b1f8099445123364ab46c Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 30 Jan 2025 09:04:00 +0100 Subject: [PATCH 192/659] wip --- reproduction-models | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reproduction-models b/reproduction-models index e55594d5ce..f8c2df656d 160000 --- a/reproduction-models +++ b/reproduction-models @@ -1 +1 @@ -Subproject commit e55594d5ce21eb064776acdea37065e0649959b3 +Subproject commit f8c2df656d6b90c064917728aa5e9aa23394a7e9 From f144f2e35b86cbda2bd21c5730ef86188f387f25 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 30 Jan 2025 16:49:58 +0100 Subject: [PATCH 193/659] =?UTF-8?q?=F0=9F=90=9B=20connector=20example=20no?= =?UTF-8?q?t=20downloading=20plugin=20when=20open=20the=20file=20in=20edit?= =?UTF-8?q?or=20is=20selected=20in=20menu=20#6234?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 45 ++++++++++++------- scripts/cli/playground.json | 7 +++ scripts/cli/playground.yaml | 6 +++ scripts/cli/src/bashly.yml | 4 ++ .../src/commands/connector/offsets/alter.sh | 6 +-- .../connector/show-config-parameters.sh | 2 +- scripts/cli/src/commands/connector/update.sh | 2 +- scripts/cli/src/commands/container/logs.sh | 2 +- scripts/cli/src/commands/debug/thread-dump.sh | 2 +- scripts/cli/src/commands/open.sh | 9 +++- scripts/cli/src/commands/repro/bootstrap.sh | 6 +-- scripts/cli/src/commands/run.sh | 4 +- scripts/cli/src/commands/update-version.sh | 2 +- scripts/cli/src/lib/utils_function.sh | 2 +- 14 files changed, 69 insertions(+), 30 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 0956eaaeb7..60f537bd72 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -9400,7 +9400,7 @@ done if [[ -n "$open" ]] then - open_file_with_editor "/tmp/jmx_metrics.log" + playground open --file "/tmp/jmx_metrics.log" fi } @@ -14223,7 +14223,7 @@ playground_run_command() { if [[ -n "$open" ]] then - open_file_with_editor "${test_file}" + playground open --file "${test_file}" check_if_continue fi @@ -14771,7 +14771,7 @@ playground_run_command() { if [[ $res == *"$MENU_OPEN_FILE"* ]] then - open_file_with_editor "${test_file}" + playground open --file "${test_file}" fi if [[ $res == *"$MENU_OPEN_DOCS"* ]] @@ -15870,7 +15870,7 @@ playground_update_version_command() { if [[ $res == *"$MENU_OPEN_FILE"* ]] then - open_file_with_editor "${test_file}" + playground open --file "${test_file}" fi if [[ $res == *"$MENU_OPEN_DOCS"* ]] @@ -16051,6 +16051,7 @@ playground_update_version_command() { playground_open_command() { # src/commands/open.sh test_file="${args[--file]}" + wait="${args[--wait]}" if [[ -n "$test_file" ]] then @@ -16069,7 +16070,13 @@ playground_open_command() { fi fi - open_file_with_editor "${test_file}" + do_wait="" + if [[ -n "$wait" ]] + then + do_wait="wait" + fi + + open_file_with_editor "${test_file}" "${do_wait}" } # :command.function @@ -17121,7 +17128,7 @@ playground_repro_bootstrap_command() { if [[ -n "$schema_file_key" ]] then log "✨ Copy and paste the schema you want to use for the key, save and close the file to continue" - open_file_with_editor "$tmp_dir/key_schema" "--wait" + playground open --file "$tmp_dir/key_schema" --wait case "${producer}" in avro-with-key) @@ -17198,7 +17205,7 @@ playground_repro_bootstrap_command() { if [[ -n "$schema_file_value" ]] then log "✨ Copy and paste the schema you want to use for the value, save and close the file to continue" - open_file_with_editor "$tmp_dir/value_schema" "--wait" + playground open --file "$tmp_dir/value_schema" --wait case "${producer}" in avro|avro-with-key) @@ -17911,7 +17918,7 @@ EOF playground state set run.test_file "$repro_dir/$repro_test_filename" playground state set run.connector_type "$(get_connector_type | tr -d '\n')" - open_file_with_editor "$repro_dir/$repro_test_filename" + playground open --file "$repro_dir/$repro_test_filename" increment_cli_metric nb_reproduction_models log "👷 Number of repro models created so far: $(get_cli_metric nb_reproduction_models)" @@ -19201,7 +19208,7 @@ playground_debug_thread_dump_command() { docker exec $container jstack 1 > "$filename" 2>&1 if [ $? -eq 0 ] then - open_file_with_editor "${filename}" + playground open --file "${filename}" else logerror "❌ Failed to take thread dump" fi @@ -19709,7 +19716,7 @@ playground_container_logs_command() { docker container logs "$container" > "$filename" 2>&1 if [ $? -eq 0 ] then - open_file_with_editor "${filename}" + playground open --file "${filename}" else logerror "❌ failed to get logs using container logs $container" fi @@ -22817,7 +22824,7 @@ playground_connector_offsets_alter_command() { cp $file_tmp $file log "✨ Update the connector offsets as per your needs, save and close the file to continue" - open_file_with_editor "${file}" "--wait" + playground open --file "${file}" --wait handle_ccloud_connect_rest_api "curl -s --request POST -H \"Content-Type: application/json\" --data @$file \"https://api.confluent.cloud/connect/v1/environments/$environment/clusters/$cluster/connectors/$connector/offsets/request\" --header \"authorization: Basic $authorization\"" else @@ -22833,7 +22840,7 @@ playground_connector_offsets_alter_command() { echo "$curl_output" | jq . > $file log "✨ Update the connector offsets as per your needs, save and close the file to continue" - open_file_with_editor "${file}" "--wait" + playground open --file "${file}" --wait playground connector stop --connector $connector @@ -22936,7 +22943,7 @@ playground_connector_offsets_alter_command() { docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector $security --export --reset-offsets --to-current --all-topics --dry-run >> $file log "✨ Update the connector offsets as per your needs, save and close the file to continue" - open_file_with_editor "${file}" "--wait" + playground open --file "${file}" --wait # remove any empty lines and header grep -v '^$' "$file" > $tmp_dir/tmp && mv $tmp_dir/tmp "$file" @@ -24027,7 +24034,7 @@ playground_connector_show_config_parameters_command() { echo "🔩 list of all available parameters for connector $connector ($class) and version $version (with default value when applicable)" >> $filename fi - open_file_with_editor "${filename}" + playground open --file "${filename}" else if [[ -n "$only_show_json" ]] || [[ -n "$only_show_json_file_path" ]] then @@ -25005,7 +25012,7 @@ playground_connector_update_command() { playground connector show-config-parameters --connector $connector | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" >> $file log "✨ Update the connector config as per your needs, save and close the file to continue" - open_file_with_editor "${file}" "--wait" + playground open --file "${file}" --wait bash $file done @@ -29598,6 +29605,14 @@ playground_open_parse_requirements() { fi ;; + # :flag.case + --wait) + + # :flag.case_no_arg + args['--wait']=1 + shift + ;; + -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index 16be5a0587..201da97b4c 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -366,6 +366,13 @@ ], "argument": "FILE", "description": "🔎 Search any file and open it.\n\n❕ It must be absolute full path\n\n🎓 Tip: use completion to trigger fzf completion\n" + }, + { + "names": [ + "--wait" + ], + "argument": "", + "description": "😴 Wait\n" } ], "subcommands": null diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index 8d2f0e7969..809d9dbb95 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -484,6 +484,12 @@ subcommands: 🎓 Tip: use completion to trigger fzf completion + - names: + - --wait + argument: "" + description: | + 😴 Wait + subcommands: - name: stop description: | diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index a47e8812fb..bda0e3d8e0 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -881,6 +881,10 @@ commands: ❕ It must be absolute full path 🎓 Tip: use completion to trigger fzf completion + - long: --wait + private: true + help: |- + 😴 Wait - name: stop group: Run diff --git a/scripts/cli/src/commands/connector/offsets/alter.sh b/scripts/cli/src/commands/connector/offsets/alter.sh index cc2cb5fb71..2eaf5c354b 100644 --- a/scripts/cli/src/commands/connector/offsets/alter.sh +++ b/scripts/cli/src/commands/connector/offsets/alter.sh @@ -67,7 +67,7 @@ function handle_first_class_offset() { cp $file_tmp $file log "✨ Update the connector offsets as per your needs, save and close the file to continue" - open_file_with_editor "${file}" "--wait" + playground open --file "${file}" --wait handle_ccloud_connect_rest_api "curl -s --request POST -H \"Content-Type: application/json\" --data @$file \"https://api.confluent.cloud/connect/v1/environments/$environment/clusters/$cluster/connectors/$connector/offsets/request\" --header \"authorization: Basic $authorization\"" else @@ -83,7 +83,7 @@ function handle_first_class_offset() { echo "$curl_output" | jq . > $file log "✨ Update the connector offsets as per your needs, save and close the file to continue" - open_file_with_editor "${file}" "--wait" + playground open --file "${file}" --wait playground connector stop --connector $connector @@ -190,7 +190,7 @@ do docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector $security --export --reset-offsets --to-current --all-topics --dry-run >> $file log "✨ Update the connector offsets as per your needs, save and close the file to continue" - open_file_with_editor "${file}" "--wait" + playground open --file "${file}" --wait # remove any empty lines and header grep -v '^$' "$file" > $tmp_dir/tmp && mv $tmp_dir/tmp "$file" diff --git a/scripts/cli/src/commands/connector/show-config-parameters.sh b/scripts/cli/src/commands/connector/show-config-parameters.sh index a5478b2570..f759ae7317 100644 --- a/scripts/cli/src/commands/connector/show-config-parameters.sh +++ b/scripts/cli/src/commands/connector/show-config-parameters.sh @@ -202,7 +202,7 @@ do echo "🔩 list of all available parameters for connector $connector ($class) and version $version (with default value when applicable)" >> $filename fi - open_file_with_editor "${filename}" + playground open --file "${filename}" else if [[ -n "$only_show_json" ]] || [[ -n "$only_show_json_file_path" ]] then diff --git a/scripts/cli/src/commands/connector/update.sh b/scripts/cli/src/commands/connector/update.sh index 01348091f4..508de86a42 100644 --- a/scripts/cli/src/commands/connector/update.sh +++ b/scripts/cli/src/commands/connector/update.sh @@ -68,6 +68,6 @@ do playground connector show-config-parameters --connector $connector | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" >> $file log "✨ Update the connector config as per your needs, save and close the file to continue" - open_file_with_editor "${file}" "--wait" + playground open --file "${file}" --wait bash $file done diff --git a/scripts/cli/src/commands/container/logs.sh b/scripts/cli/src/commands/container/logs.sh index 1f0c556ce7..25f876ee25 100644 --- a/scripts/cli/src/commands/container/logs.sh +++ b/scripts/cli/src/commands/container/logs.sh @@ -9,7 +9,7 @@ then docker container logs "$container" > "$filename" 2>&1 if [ $? -eq 0 ] then - open_file_with_editor "${filename}" + playground open --file "${filename}" else logerror "❌ failed to get logs using container logs $container" fi diff --git a/scripts/cli/src/commands/debug/thread-dump.sh b/scripts/cli/src/commands/debug/thread-dump.sh index 0b39a45cd8..96d5d136d4 100644 --- a/scripts/cli/src/commands/debug/thread-dump.sh +++ b/scripts/cli/src/commands/debug/thread-dump.sh @@ -13,7 +13,7 @@ log "🎯 Taking thread dump on container ${container} for pid 1" docker exec $container jstack 1 > "$filename" 2>&1 if [ $? -eq 0 ] then - open_file_with_editor "${filename}" + playground open --file "${filename}" else logerror "❌ Failed to take thread dump" fi \ No newline at end of file diff --git a/scripts/cli/src/commands/open.sh b/scripts/cli/src/commands/open.sh index 346b1a2cb2..dc876edfca 100644 --- a/scripts/cli/src/commands/open.sh +++ b/scripts/cli/src/commands/open.sh @@ -1,4 +1,5 @@ test_file="${args[--file]}" +wait="${args[--wait]}" if [[ -n "$test_file" ]] then @@ -16,4 +17,10 @@ else fi fi -open_file_with_editor "${test_file}" \ No newline at end of file +do_wait="" +if [[ -n "$wait" ]] +then + do_wait="wait" +fi + +open_file_with_editor "${test_file}" "${do_wait}" \ No newline at end of file diff --git a/scripts/cli/src/commands/repro/bootstrap.sh b/scripts/cli/src/commands/repro/bootstrap.sh index 1de03a8535..6948f0624e 100644 --- a/scripts/cli/src/commands/repro/bootstrap.sh +++ b/scripts/cli/src/commands/repro/bootstrap.sh @@ -463,7 +463,7 @@ then if [[ -n "$schema_file_key" ]] then log "✨ Copy and paste the schema you want to use for the key, save and close the file to continue" - open_file_with_editor "$tmp_dir/key_schema" "--wait" + playground open --file "$tmp_dir/key_schema" --wait case "${producer}" in avro-with-key) @@ -542,7 +542,7 @@ then if [[ -n "$schema_file_value" ]] then log "✨ Copy and paste the schema you want to use for the value, save and close the file to continue" - open_file_with_editor "$tmp_dir/value_schema" "--wait" + playground open --file "$tmp_dir/value_schema" --wait case "${producer}" in avro|avro-with-key) @@ -1258,7 +1258,7 @@ fi playground state set run.test_file "$repro_dir/$repro_test_filename" playground state set run.connector_type "$(get_connector_type | tr -d '\n')" -open_file_with_editor "$repro_dir/$repro_test_filename" +playground open --file "$repro_dir/$repro_test_filename" increment_cli_metric nb_reproduction_models log "👷 Number of repro models created so far: $(get_cli_metric nb_reproduction_models)" diff --git a/scripts/cli/src/commands/run.sh b/scripts/cli/src/commands/run.sh index b46fde97ad..4a21050094 100644 --- a/scripts/cli/src/commands/run.sh +++ b/scripts/cli/src/commands/run.sh @@ -415,7 +415,7 @@ fi if [[ -n "$open" ]] then - open_file_with_editor "${test_file}" + playground open --file "${test_file}" check_if_continue fi @@ -956,7 +956,7 @@ then if [[ $res == *"$MENU_OPEN_FILE"* ]] then - open_file_with_editor "${test_file}" + playground open --file "${test_file}" fi if [[ $res == *"$MENU_OPEN_DOCS"* ]] diff --git a/scripts/cli/src/commands/update-version.sh b/scripts/cli/src/commands/update-version.sh index e66ac7be6f..bf1884738c 100644 --- a/scripts/cli/src/commands/update-version.sh +++ b/scripts/cli/src/commands/update-version.sh @@ -257,7 +257,7 @@ then if [[ $res == *"$MENU_OPEN_FILE"* ]] then - open_file_with_editor "${test_file}" + playground open --file "${test_file}" fi if [[ $res == *"$MENU_OPEN_DOCS"* ]] diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 75528e3bf2..52378a22fd 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -1157,7 +1157,7 @@ done if [[ -n "$open" ]] then - open_file_with_editor "/tmp/jmx_metrics.log" + playground open --file "/tmp/jmx_metrics.log" fi } From 1138275f0371727ae654f212aa8e94e76219c4e1 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 3 Feb 2025 10:34:24 +0100 Subject: [PATCH 194/659] ports --- environment/mdc-plaintext/docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/environment/mdc-plaintext/docker-compose.yml b/environment/mdc-plaintext/docker-compose.yml index eb6d6dfd75..3ee2404ebf 100644 --- a/environment/mdc-plaintext/docker-compose.yml +++ b/environment/mdc-plaintext/docker-compose.yml @@ -111,7 +111,7 @@ services: hostname: connect-us container_name: connect-us ports: - - "28083:8083" + - "8083:8083" - "5005:5005" depends_on: - zookeeper-us @@ -157,7 +157,7 @@ services: hostname: connect-europe container_name: connect-europe ports: - - "18083:8083" + - "8283:8083" - "5006:5005" depends_on: - zookeeper-europe From 469378a14e78687c89b89524064aaa0d16ed0226 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 3 Feb 2025 14:45:19 +0100 Subject: [PATCH 195/659] disable ssl logging --- .../docker-compose.plaintext.mtls-proxy.yml | 2 +- .../connect-http-cdc-source/docker-compose.plaintext.mtls.yml | 2 +- connect/connect-ibm-mq-sink/docker-compose.plaintext.mtls.yml | 2 +- connect/connect-ibm-mq-sink/docker-compose.plaintext.ssl.yml | 2 +- connect/connect-ibm-mq-source/docker-compose.plaintext.mtls.yml | 2 +- connect/connect-ibm-mq-source/docker-compose.plaintext.ssl.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/connect/connect-http-cdc-source/docker-compose.plaintext.mtls-proxy.yml b/connect/connect-http-cdc-source/docker-compose.plaintext.mtls-proxy.yml index 4314a19673..d6d2982e85 100644 --- a/connect/connect-http-cdc-source/docker-compose.plaintext.mtls-proxy.yml +++ b/connect/connect-http-cdc-source/docker-compose.plaintext.mtls-proxy.yml @@ -18,7 +18,7 @@ services: KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.http-service-mtls-auth.p12 -Djavax.net.ssl.trustStorePassword=confluent -Djavax.net.ssl.trustStoreType=PKCS12 - -Djavax.net.debug=all + # -Djavax.net.debug=all -Dhttp.proxyHost=nginx-proxy -Dhttp.proxyPort=8888 -Dhttps.proxyHost=nginx-proxy diff --git a/connect/connect-http-cdc-source/docker-compose.plaintext.mtls.yml b/connect/connect-http-cdc-source/docker-compose.plaintext.mtls.yml index 50d75e6856..0ce675d0ba 100644 --- a/connect/connect-http-cdc-source/docker-compose.plaintext.mtls.yml +++ b/connect/connect-http-cdc-source/docker-compose.plaintext.mtls.yml @@ -9,7 +9,7 @@ services: KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.http-service-mtls-auth.p12 -Djavax.net.ssl.trustStorePassword=confluent -Djavax.net.ssl.trustStoreType=PKCS12 - -Djavax.net.debug=all + # -Djavax.net.debug=all #-Djdk.tls.client.protocols=TLSv1.2 # -Djavax.net.ssl.keyStore=/tmp/keystore.http-service-mtls-auth.jks diff --git a/connect/connect-ibm-mq-sink/docker-compose.plaintext.mtls.yml b/connect/connect-ibm-mq-sink/docker-compose.plaintext.mtls.yml index 017275603f..bcf738061e 100644 --- a/connect/connect-ibm-mq-sink/docker-compose.plaintext.mtls.yml +++ b/connect/connect-ibm-mq-sink/docker-compose.plaintext.mtls.yml @@ -30,4 +30,4 @@ services: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-ibmmq-sink # https://support.confluent.io/hc/en-us/articles/360054967632-What-cause-the-IBMMQ-connector-fail-to-establish-a-SSL-connection-with-Cipher-Error KAFKA_OPTS: -Dcom.ibm.mq.cfg.useIBMCipherMappings=false - -Djavax.net.debug=all \ No newline at end of file + # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-ibm-mq-sink/docker-compose.plaintext.ssl.yml b/connect/connect-ibm-mq-sink/docker-compose.plaintext.ssl.yml index 67f6f8f84c..aea4a175ad 100644 --- a/connect/connect-ibm-mq-sink/docker-compose.plaintext.ssl.yml +++ b/connect/connect-ibm-mq-sink/docker-compose.plaintext.ssl.yml @@ -28,4 +28,4 @@ services: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-ibmmq-sink # https://support.confluent.io/hc/en-us/articles/360054967632-What-cause-the-IBMMQ-connector-fail-to-establish-a-SSL-connection-with-Cipher-Error KAFKA_OPTS: -Dcom.ibm.mq.cfg.useIBMCipherMappings=false - -Djavax.net.debug=all \ No newline at end of file + # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-ibm-mq-source/docker-compose.plaintext.mtls.yml b/connect/connect-ibm-mq-source/docker-compose.plaintext.mtls.yml index 3ef9ee30de..3797a84ab2 100644 --- a/connect/connect-ibm-mq-source/docker-compose.plaintext.mtls.yml +++ b/connect/connect-ibm-mq-source/docker-compose.plaintext.mtls.yml @@ -30,4 +30,4 @@ services: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-ibmmq # https://support.confluent.io/hc/en-us/articles/360054967632-What-cause-the-IBMMQ-connector-fail-to-establish-a-SSL-connection-with-Cipher-Error KAFKA_OPTS: -Dcom.ibm.mq.cfg.useIBMCipherMappings=false - -Djavax.net.debug=all + # -Djavax.net.debug=all diff --git a/connect/connect-ibm-mq-source/docker-compose.plaintext.ssl.yml b/connect/connect-ibm-mq-source/docker-compose.plaintext.ssl.yml index 3b8cb88bed..a516a2f2de 100644 --- a/connect/connect-ibm-mq-source/docker-compose.plaintext.ssl.yml +++ b/connect/connect-ibm-mq-source/docker-compose.plaintext.ssl.yml @@ -28,4 +28,4 @@ services: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-ibmmq # https://support.confluent.io/hc/en-us/articles/360054967632-What-cause-the-IBMMQ-connector-fail-to-establish-a-SSL-connection-with-Cipher-Error KAFKA_OPTS: -Dcom.ibm.mq.cfg.useIBMCipherMappings=false - -Djavax.net.debug=all + # -Djavax.net.debug=all From 11b40da20794a88cc2d5def4b0309fb0c9ad0e50 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 3 Feb 2025 15:08:04 +0100 Subject: [PATCH 196/659] "max.retry.time": "10000" --- connect/connect-ibm-mq-source/ibm-mq-mtls.sh | 1 + connect/connect-ibm-mq-source/ibm-mq-ssl.sh | 1 + connect/connect-ibm-mq-source/ibm-mq.sh | 1 + 3 files changed, 3 insertions(+) diff --git a/connect/connect-ibm-mq-source/ibm-mq-mtls.sh b/connect/connect-ibm-mq-source/ibm-mq-mtls.sh index f1bb9a36df..e23c823185 100755 --- a/connect/connect-ibm-mq-source/ibm-mq-mtls.sh +++ b/connect/connect-ibm-mq-source/ibm-mq-mtls.sh @@ -69,6 +69,7 @@ playground connector create-or-update --connector ibm-mq-source-mtls << EOF "mq.channel": "DEV.APP.SVRCONN", "mq.username": "", "mq.password": "", + "max.retry.time": "10000", "jms.destination.name": "DEV.QUEUE.1", "jms.destination.type": "queue", "mq.tls.truststore.location": "/tmp/truststore.jks", diff --git a/connect/connect-ibm-mq-source/ibm-mq-ssl.sh b/connect/connect-ibm-mq-source/ibm-mq-ssl.sh index 27d8d68c4e..5c1671386c 100755 --- a/connect/connect-ibm-mq-source/ibm-mq-ssl.sh +++ b/connect/connect-ibm-mq-source/ibm-mq-ssl.sh @@ -56,6 +56,7 @@ playground connector create-or-update --connector ibm-mq-source-ssl << EOF "mq.channel": "DEV.APP.SVRCONN", "mq.username": "app", "mq.password": "passw0rd", + "max.retry.time": "10000", "jms.destination.name": "DEV.QUEUE.1", "jms.destination.type": "queue", "mq.tls.truststore.location": "/tmp/truststore.jks", diff --git a/connect/connect-ibm-mq-source/ibm-mq.sh b/connect/connect-ibm-mq-source/ibm-mq.sh index a8dca816d0..d66e7a49be 100755 --- a/connect/connect-ibm-mq-source/ibm-mq.sh +++ b/connect/connect-ibm-mq-source/ibm-mq.sh @@ -47,6 +47,7 @@ playground connector create-or-update --connector ibm-mq-source << EOF "mq.channel": "DEV.APP.SVRCONN", "mq.username": "app", "mq.password": "passw0rd", + "max.retry.time": "10000", "jms.destination.name": "DEV.QUEUE.1", "jms.destination.type": "queue", "confluent.license": "", From 4148a3bea1da0b45ab7940eddbf08b509388466b Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 3 Feb 2025 15:11:10 +0100 Subject: [PATCH 197/659] wait_container_ready for recreate --- scripts/cli/playground | 2 ++ scripts/cli/src/commands/container/recreate.sh | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 60f537bd72..2d14a4ca83 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -19686,6 +19686,8 @@ playground_container_recreate_command() { echo "$docker_command" > /tmp/playground-command log "💫 Recreate container(s)" bash /tmp/playground-command + + wait_container_ready } # :command.function diff --git a/scripts/cli/src/commands/container/recreate.sh b/scripts/cli/src/commands/container/recreate.sh index 954797cf57..dab8f57a3c 100644 --- a/scripts/cli/src/commands/container/recreate.sh +++ b/scripts/cli/src/commands/container/recreate.sh @@ -35,4 +35,6 @@ fi echo "$docker_command" > /tmp/playground-command log "💫 Recreate container(s)" -bash /tmp/playground-command \ No newline at end of file +bash /tmp/playground-command + +wait_container_ready \ No newline at end of file From 886706a6e79d90f4fc46f07c11e3045bf15c4fd7 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 4 Feb 2025 10:58:38 +0100 Subject: [PATCH 198/659] add retries for functions url --- .../fully-managed-azure-functions-sink.sh | 30 +++++++++++++----- .../azure-functions-sink.sh | 31 ++++++++++++++----- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh b/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh index 2ae2268412..24c29275f9 100755 --- a/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh +++ b/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh @@ -79,7 +79,7 @@ until docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/ do if (( attempt_num == max_attempts )) then - logerror "ERROR: Failed after $attempt_num attempts. Please troubleshoot and run again." + logerror "❌ Failed after $attempt_num attempts. Please troubleshoot and run again." exit 1 else log "Retrying after $sleep_interval seconds" @@ -88,14 +88,30 @@ do fi done +max_attempts="10" +sleep_interval="30" +attempt_num=1 -output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions $AZURE_FUNCTIONS_NAME --show-keys") -FUNCTIONS_URL=$(echo "$output" | grep "Invoke url" | grep -Eo 'https://[^ >]+'|head -1) +until [ ! -z "$FUNCTIONS_URL" ] +do + output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions $AZURE_FUNCTIONS_NAME --show-keys") + FUNCTIONS_URL=$(echo "$output" | grep "Invoke url" | grep -Eo 'https://[^ >]+' | head -1) -if [ -z "$GITHUB_RUN_NUMBER" ] -then - log "Functions URL is $FUNCTIONS_URL" -fi + if [ ! -z "$FUNCTIONS_URL" ] + then + log "Functions URL is $FUNCTIONS_URL" + else + if (( attempt_num == max_attempts )) + then + logerror "❌ Failed to retrieve FUNCTIONS_URL after $attempt_num attempts. Please troubleshoot and run again." + exit 1 + else + log "Retrying to get FUNCTIONS_URL after $sleep_interval seconds" + ((attempt_num++)) + sleep $sleep_interval + fi + fi +done bootstrap_ccloud_environment diff --git a/connect/connect-azure-functions-sink/azure-functions-sink.sh b/connect/connect-azure-functions-sink/azure-functions-sink.sh index 4354d68f9a..4fae7681ec 100755 --- a/connect/connect-azure-functions-sink/azure-functions-sink.sh +++ b/connect/connect-azure-functions-sink/azure-functions-sink.sh @@ -79,7 +79,7 @@ until docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/ do if (( attempt_num == max_attempts )) then - logerror "ERROR: Failed after $attempt_num attempts. Please troubleshoot and run again." + logerror "❌ Failed after $attempt_num attempts. Please troubleshoot and run again." exit 1 else log "Retrying after $sleep_interval seconds" @@ -88,15 +88,30 @@ do fi done +max_attempts="10" +sleep_interval="30" +attempt_num=1 -output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions $AZURE_FUNCTIONS_NAME --show-keys") -FUNCTIONS_URL=$(echo "$output" | grep "Invoke url" | grep -Eo 'https://[^ >]+'|head -1) +until [ ! -z "$FUNCTIONS_URL" ] +do + output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions $AZURE_FUNCTIONS_NAME --show-keys") + FUNCTIONS_URL=$(echo "$output" | grep "Invoke url" | grep -Eo 'https://[^ >]+' | head -1) -echo "$output" -# if [ -z "$GITHUB_RUN_NUMBER" ] -# then - log "Functions URL is $FUNCTIONS_URL" -# fi + if [ ! -z "$FUNCTIONS_URL" ] + then + log "Functions URL is $FUNCTIONS_URL" + else + if (( attempt_num == max_attempts )) + then + logerror "❌ Failed to retrieve FUNCTIONS_URL after $attempt_num attempts. Please troubleshoot and run again." + exit 1 + else + log "Retrying to get FUNCTIONS_URL after $sleep_interval seconds" + ((attempt_num++)) + sleep $sleep_interval + fi + fi +done PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" From 7b19d098c1225b40ca7518e461a8f00fca96ec7b Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 4 Feb 2025 11:23:52 +0100 Subject: [PATCH 199/659] debug --- connect/connect-azure-functions-sink/azure-functions-sink.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/connect/connect-azure-functions-sink/azure-functions-sink.sh b/connect/connect-azure-functions-sink/azure-functions-sink.sh index 4fae7681ec..f24d236d36 100755 --- a/connect/connect-azure-functions-sink/azure-functions-sink.sh +++ b/connect/connect-azure-functions-sink/azure-functions-sink.sh @@ -95,6 +95,10 @@ attempt_num=1 until [ ! -z "$FUNCTIONS_URL" ] do output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions $AZURE_FUNCTIONS_NAME --show-keys") + + log "before echo" + echo "$output" + log "after echo" FUNCTIONS_URL=$(echo "$output" | grep "Invoke url" | grep -Eo 'https://[^ >]+' | head -1) if [ ! -z "$FUNCTIONS_URL" ] From 3ee9a9b7f8e9f886b4fcf3febeafd8974397cab9 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 4 Feb 2025 12:22:59 +0100 Subject: [PATCH 200/659] retries --- .../azure-functions-sink.sh | 38 +++++++++++++++++-- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/connect/connect-azure-functions-sink/azure-functions-sink.sh b/connect/connect-azure-functions-sink/azure-functions-sink.sh index f24d236d36..6ce93078c9 100755 --- a/connect/connect-azure-functions-sink/azure-functions-sink.sh +++ b/connect/connect-azure-functions-sink/azure-functions-sink.sh @@ -68,7 +68,40 @@ log "Creating local functions project with HTTP trigger" docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "func init LocalFunctionProj --javascript && cd LocalFunctionProj && func new --name HttpExample --template \"HTTP trigger\" --authlevel \"anonymous\"" log "Creating functions app $AZURE_FUNCTIONS_NAME" -az functionapp create --consumption-plan-location $AZURE_REGION --name $AZURE_FUNCTIONS_NAME --resource-group $AZURE_RESOURCE_GROUP --runtime node --storage-account $AZURE_STORAGE_NAME --runtime-version 18 --functions-version 4 --tags owner_email=$AZ_USER --disable-app-insights true +max_attempts="10" +sleep_interval="30" +attempt_num=1 + +until az functionapp create --consumption-plan-location $AZURE_REGION --name $AZURE_FUNCTIONS_NAME --resource-group $AZURE_RESOURCE_GROUP --runtime node --storage-account $AZURE_STORAGE_NAME --runtime-version 18 --functions-version 4 --tags owner_email=$AZ_USER --disable-app-insights true > /dev/null 2>&1 +do + if (( attempt_num == max_attempts )) + then + logerror "❌ Failed to create function app after $attempt_num attempts. Please troubleshoot and run again." + exit 1 + else + log "Retrying to create function app after $sleep_interval seconds" + ((attempt_num++)) + sleep $sleep_interval + fi +done + +# Verify the creation by listing the function apps in the resource group +max_attempts="10" +sleep_interval="30" +attempt_num=1 + +until az functionapp list --resource-group $AZURE_RESOURCE_GROUP --query "[?name=='$AZURE_FUNCTIONS_NAME']" --output table | grep -q "$AZURE_FUNCTIONS_NAME" +do + if (( attempt_num == max_attempts )) + then + logerror "❌ Failed to verify function app creation after $attempt_num attempts. Please troubleshoot and run again." + exit 1 + else + log "Retrying to verify function app creation after $sleep_interval seconds" + ((attempt_num++)) + sleep $sleep_interval + fi +done log "Publishing functions app, it will take a while" max_attempts="10" @@ -96,9 +129,6 @@ until [ ! -z "$FUNCTIONS_URL" ] do output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions $AZURE_FUNCTIONS_NAME --show-keys") - log "before echo" - echo "$output" - log "after echo" FUNCTIONS_URL=$(echo "$output" | grep "Invoke url" | grep -Eo 'https://[^ >]+' | head -1) if [ ! -z "$FUNCTIONS_URL" ] From 50d7938391a2ded3b432e159888e2f472dbdf908 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 4 Feb 2025 13:41:25 +0100 Subject: [PATCH 201/659] wip --- .../azure-functions-sink.sh | 44 +++++-------------- 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/connect/connect-azure-functions-sink/azure-functions-sink.sh b/connect/connect-azure-functions-sink/azure-functions-sink.sh index 6ce93078c9..ba7e519555 100755 --- a/connect/connect-azure-functions-sink/azure-functions-sink.sh +++ b/connect/connect-azure-functions-sink/azure-functions-sink.sh @@ -68,40 +68,18 @@ log "Creating local functions project with HTTP trigger" docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "func init LocalFunctionProj --javascript && cd LocalFunctionProj && func new --name HttpExample --template \"HTTP trigger\" --authlevel \"anonymous\"" log "Creating functions app $AZURE_FUNCTIONS_NAME" -max_attempts="10" -sleep_interval="30" -attempt_num=1 +az functionapp create --consumption-plan-location "$AZURE_REGION" --name "$AZURE_FUNCTIONS_NAME" --resource-group "$AZURE_RESOURCE_GROUP" --runtime node --storage-account "$AZURE_STORAGE_NAME" --runtime-version 18 --functions-version 4 --tags owner_email="$AZ_USER" --disable-app-insights true -until az functionapp create --consumption-plan-location $AZURE_REGION --name $AZURE_FUNCTIONS_NAME --resource-group $AZURE_RESOURCE_GROUP --runtime node --storage-account $AZURE_STORAGE_NAME --runtime-version 18 --functions-version 4 --tags owner_email=$AZ_USER --disable-app-insights true > /dev/null 2>&1 -do - if (( attempt_num == max_attempts )) - then - logerror "❌ Failed to create function app after $attempt_num attempts. Please troubleshoot and run again." - exit 1 - else - log "Retrying to create function app after $sleep_interval seconds" - ((attempt_num++)) - sleep $sleep_interval - fi -done - -# Verify the creation by listing the function apps in the resource group -max_attempts="10" -sleep_interval="30" -attempt_num=1 +# Check if the function app was created successfully +if [ $? -eq 0 ] +then + log "Azure Function App created successfully." +else + logerror "❌ Failed to create Azure Function App." + exit 1 +fi -until az functionapp list --resource-group $AZURE_RESOURCE_GROUP --query "[?name=='$AZURE_FUNCTIONS_NAME']" --output table | grep -q "$AZURE_FUNCTIONS_NAME" -do - if (( attempt_num == max_attempts )) - then - logerror "❌ Failed to verify function app creation after $attempt_num attempts. Please troubleshoot and run again." - exit 1 - else - log "Retrying to verify function app creation after $sleep_interval seconds" - ((attempt_num++)) - sleep $sleep_interval - fi -done +sleep 10 log "Publishing functions app, it will take a while" max_attempts="10" @@ -129,6 +107,8 @@ until [ ! -z "$FUNCTIONS_URL" ] do output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions $AZURE_FUNCTIONS_NAME --show-keys") + log "Output from list-functions command: $output" + FUNCTIONS_URL=$(echo "$output" | grep "Invoke url" | grep -Eo 'https://[^ >]+' | head -1) if [ ! -z "$FUNCTIONS_URL" ] From 77c7d184f23946f1905d1fd543a2a20d33b8c064 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 4 Feb 2025 14:54:15 +0100 Subject: [PATCH 202/659] wip --- .../connect-azure-functions-sink/azure-functions-sink.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/connect/connect-azure-functions-sink/azure-functions-sink.sh b/connect/connect-azure-functions-sink/azure-functions-sink.sh index ba7e519555..b5b06111f4 100755 --- a/connect/connect-azure-functions-sink/azure-functions-sink.sh +++ b/connect/connect-azure-functions-sink/azure-functions-sink.sh @@ -81,7 +81,7 @@ fi sleep 10 -log "Publishing functions app, it will take a while" +log "Publishing functions app $AZURE_FUNCTIONS_NAME, it will take a while" max_attempts="10" sleep_interval="60" attempt_num=1 @@ -99,13 +99,16 @@ do fi done +curl -s https://$AZURE_FUNCTIONS_NAME.azurewebsites.net/" > /dev/null +curl -s https://$AZURE_FUNCTIONS_NAME.azurewebsites.net/api/httpexample" > /dev/null + max_attempts="10" sleep_interval="30" attempt_num=1 until [ ! -z "$FUNCTIONS_URL" ] do - output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions $AZURE_FUNCTIONS_NAME --show-keys") + output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions \"$AZURE_FUNCTIONS_NAME\" --show-keys") log "Output from list-functions command: $output" From 19914a2efb5a640c68a03906612d653901e63c96 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 4 Feb 2025 14:54:37 +0100 Subject: [PATCH 203/659] wip --- connect/connect-azure-functions-sink/azure-functions-sink.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/connect/connect-azure-functions-sink/azure-functions-sink.sh b/connect/connect-azure-functions-sink/azure-functions-sink.sh index b5b06111f4..89cf1faede 100755 --- a/connect/connect-azure-functions-sink/azure-functions-sink.sh +++ b/connect/connect-azure-functions-sink/azure-functions-sink.sh @@ -99,9 +99,12 @@ do fi done +set +e curl -s https://$AZURE_FUNCTIONS_NAME.azurewebsites.net/" > /dev/null curl -s https://$AZURE_FUNCTIONS_NAME.azurewebsites.net/api/httpexample" > /dev/null +set -e + max_attempts="10" sleep_interval="30" attempt_num=1 From 79492152795b7f4b9f36cfdd3262afacf34c36c6 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 5 Feb 2025 10:34:20 +0100 Subject: [PATCH 204/659] cosmetic --- ...-topic-offset-and-partition-not-working.sh | 2 +- .../fully-managed-azure-event-hubs.sh | 2 +- .../fully-managed-azure-service-bus-source.sh | 2 +- .../fully-managed-debezium-legacy-mysql.sh | 2 +- .../fully-managed-debezium-v2-mysql.sh | 2 +- .../fully-managed-legacy-postgres.sh | 2 +- .../fully-managed-v2-postgres.sh | 2 +- ...anaged-debezium-legacy-sqlserver-source.sh | 2 +- ...ly-managed-debezium-v2-sqlserver-source.sh | 2 +- .../fully-managed-gcp-bigquery-sink-legacy.sh | 2 +- .../fully-managed-gcp-bigquery-sink-v2.sh | 2 +- .../fully-managed-gcp-bigtable-sink.sh | 2 +- ...anaged-google-cloud-functions-gen2-sink.sh | 2 +- ...aged-google-cloud-functions-legacy-sink.sh | 2 +- .../fm-gcp-gcs-sink/fully-managed-gcs-sink.sh | 2 +- .../fully-managed-gcs-source.sh | 2 +- .../fully-managed-gcp-pubsub-source.sh | 2 +- .../fully-managed-gcp-spanner-sink.sh | 2 +- ...-managed-salesforce-cdc-source-jwt-flow.sh | 2 +- ccloud/haproxy/start.sh | 2 +- .../executable-onprem-to-cloud-avro.sh | 2 +- .../replicator/executable-onprem-to-cloud.sh | 2 +- connect/connect-amps-source/amps-source.sh | 2 +- .../appdynamics-metrics-sink.sh | 2 +- .../cloudwatch-with-assuming-iam-role.sh | 2 +- ...tch-metrics-sink-with-assuming-iam-role.sh | 2 +- .../dynamodb-sink-with-assuming-iam-role.sh | 2 +- ...h-custom-basic-aws-credentials-provider.sh | 2 +- ...role-with-custom-awscredentialsprovider.sh | 2 +- .../kinesis-source-with-assuming-iam-role.sh | 2 +- ...ole-with-custom-aws-credential-provider.sh | 2 +- .../lambda-sink-with-assuming-iam-role.sh | 2 +- .../redshift-sink-with-assuming-iam-role.sh | 2 +- ...ole-with-custom-aws-credential-provider.sh | 2 +- .../s3-sink-proxy-with-assuming-iam-role.sh | 2 +- .../s3-sink-with-assuming-iam-role.sh | 2 +- ...ole-with-custom-aws-credential-provider.sh | 2 +- ...ckup-and-restore-with-assuming-iam-role.sh | 2 +- ...ole-with-custom-aws-credential-provider.sh | 2 +- .../sqs-source-with-assuming-iam-role.sh | 2 +- .../azure-event-hubs-source.sh | 2 +- .../azure-service-bus-source.sh | 2 +- .../cdc-oracle11-source.sh | 2 +- .../cdc-oracle12-cdb-table.sh | 2 +- .../cdc-oracle12-pdb-table.sh | 2 +- .../cdc-oracle18-cdb-table.sh | 2 +- .../cdc-oracle18-pdb-table.sh | 2 +- .../cdc-oracle19-cdb-table.sh | 2 +- .../cdc-oracle19-pdb-table.sh | 2 +- .../cdc-oracle21-cdb-table.sh | 2 +- .../cdc-oracle21-pdb-table.sh | 2 +- .../connect-couchbase-sink/couchbase-sink.sh | 2 +- .../debezium-mysql-source.sh | 2 +- .../debezium-oracle19.sh | 4 +- .../debezium-postgres-source.sh | 2 +- .../debezium-sqlserver-source.sh | 2 +- .../gcp-bigquery-sink.sh | 2 +- .../gcp-bigtable-sink-proxy.sh | 2 +- .../gcp-bigtable-sink.sh | 2 +- .../google-cloud-functions-sink.sh | 2 +- .../gcp-dataproc-sink.sh | 2 +- .../gcp-firebase-sink.sh | 2 +- .../gcp-firebase-source.sh | 2 +- connect/connect-gcp-gcs-sink/gcs-sink.sh | 2 +- .../gcs-source-backup-and-restore.sh | 2 +- .../gcs-source-generalized.sh | 2 +- .../gcp-google-pubsub-sink.sh | 2 +- .../gcp-google-pubsub-source.sh | 2 +- .../gcp-pubsub-source-nginx-proxy.sh | 2 +- .../gcp-pubsub-source.sh | 2 +- .../gcp-spanner-sink-proxy.sh | 2 +- .../gcp-spanner-sink.sh | 2 +- connect/connect-graphdb-sink/graphdb-sink.sh | 2 +- .../connect-ibm-mq-sink/ibm-mq-sink-mtls.sh | 2 +- .../connect-ibm-mq-sink/ibm-mq-sink-ssl.sh | 2 +- connect/connect-ibm-mq-sink/ibm-mq-sink.sh | 2 +- connect/connect-ibm-mq-source/ibm-mq-mtls.sh | 2 +- connect/connect-ibm-mq-source/ibm-mq-ssl.sh | 2 +- connect/connect-ibm-mq-source/ibm-mq.sh | 2 +- .../athena-jdbc-source.sh | 4 +- .../jdbc-gcp-bigquery-source.sh | 2 +- connect/connect-jdbc-mysql-source/mysql.sh | 2 +- .../connect-jdbc-oracle11-source/oracle11.sh | 2 +- .../connect-jdbc-oracle12-source/oracle12.sh | 2 +- .../connect-jdbc-oracle19-source/oracle19.sh | 2 +- .../connect-jdbc-oracle21-source/oracle21.sh | 2 +- .../postgres.sh | 2 +- .../sqlserver-jtds.sh | 2 +- .../sqlserver-microsoft.sh | 2 +- .../jms-tibco-ems-sink.sh | 2 +- connect/connect-jms-tibco-source/jms-tibco.sh | 2 +- .../jms-weblogic-sink.sh | 2 +- .../jms-weblogic-source.sh | 2 +- connect/connect-kudu-sink/kudu-sink.sh | 2 +- connect/connect-kudu-source/kudu-source.sh | 2 +- .../pivotal-gemfire-sink.sh | 2 +- .../salesforce-cdc-source-jwt-flow.sh | 2 +- .../connect-sap-hana-sink/sap-hana-sink.sh | 2 +- connect/connect-tibco-sink/tibco-ems-sink.sh | 2 +- connect/connect-tibco-source/tibco-ems.sh | 2 +- .../connect-weblogic-source/weblogic-queue.sh | 2 +- .../connect-weblogic-source/weblogic-topic.sh | 2 +- other/custom-smt/filestream-sink.sh | 2 +- other/http-proxy-schema-registry/start.sh | 2 +- other/monitoring-demo/start.sh | 2 +- other/schema-format-avro-with-key/start.sh | 2 +- other/schema-format-avro/start.sh | 2 +- .../start.sh | 2 +- other/schema-format-json-schema/start.sh | 2 +- .../schema-format-protobuf-with-key/start.sh | 2 +- other/schema-format-protobuf/start.sh | 2 +- other/tiered-storage-with-aws/start.sh | 4 +- reproduction-models | 2 +- .../start-avro.sh | 2 +- scripts/cli/playground | 82 +++++++++---------- .../src/commands/cleanup-cloud-resources.sh | 4 +- .../src/commands/connector/offsets/alter.sh | 4 +- .../offsets/get-offsets-request-status.sh | 4 +- .../cli/src/commands/connector/offsets/get.sh | 4 +- .../src/commands/connector/offsets/reset.sh | 4 +- .../cli/src/commands/connector/show-lag.sh | 4 +- .../cli/src/commands/connector/snippets.sh | 2 +- .../cli/src/commands/container/recreate.sh | 2 +- scripts/cli/src/commands/get-jmx-metrics.sh | 2 +- scripts/cli/src/commands/repro/bootstrap.sh | 4 +- scripts/cli/src/commands/run.sh | 4 +- scripts/cli/src/commands/topic/alter.sh | 4 +- scripts/cli/src/commands/topic/consume.sh | 4 +- scripts/cli/src/commands/topic/create.sh | 4 +- scripts/cli/src/commands/topic/delete.sh | 4 +- scripts/cli/src/commands/topic/describe.sh | 4 +- .../src/commands/topic/get-number-records.sh | 2 +- scripts/cli/src/commands/topic/produce.sh | 6 +- scripts/cli/src/lib/cli_function.sh | 6 +- scripts/cli/src/lib/utils_function.sh | 10 +-- .../start.sh | 2 +- .../start.sh | 2 +- .../start.sh | 2 +- .../start.sh | 2 +- .../small-retention/old-timestamp.sh | 2 +- .../staled-consumer-group-behaviour/start.sh | 2 +- 141 files changed, 205 insertions(+), 205 deletions(-) diff --git a/academy/connect-connect-jdbc-mysql-source/mysql-repro-000005-insertfield-smt:-adding-topic-offset-and-partition-not-working.sh b/academy/connect-connect-jdbc-mysql-source/mysql-repro-000005-insertfield-smt:-adding-topic-offset-and-partition-not-working.sh index b255469d15..32e8eb6097 100755 --- a/academy/connect-connect-jdbc-mysql-source/mysql-repro-000005-insertfield-smt:-adding-topic-offset-and-partition-not-working.sh +++ b/academy/connect-connect-jdbc-mysql-source/mysql-repro-000005-insertfield-smt:-adding-topic-offset-and-partition-not-working.sh @@ -22,7 +22,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/ccloud/fm-azure-event-hubs-source/fully-managed-azure-event-hubs.sh b/ccloud/fm-azure-event-hubs-source/fully-managed-azure-event-hubs.sh index 9f483e41b6..3286983c3e 100755 --- a/ccloud/fm-azure-event-hubs-source/fully-managed-azure-event-hubs.sh +++ b/ccloud/fm-azure-event-hubs-source/fully-managed-azure-event-hubs.sh @@ -12,7 +12,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/ccloud/fm-azure-service-bus-source/fully-managed-azure-service-bus-source.sh b/ccloud/fm-azure-service-bus-source/fully-managed-azure-service-bus-source.sh index 165ce1d762..5246f9fb13 100755 --- a/ccloud/fm-azure-service-bus-source/fully-managed-azure-service-bus-source.sh +++ b/ccloud/fm-azure-service-bus-source/fully-managed-azure-service-bus-source.sh @@ -12,7 +12,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh b/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh index 975c3a71db..1b77ad00b1 100755 --- a/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh +++ b/ccloud/fm-debezium-mysql-legacy-source/fully-managed-debezium-legacy-mysql.sh @@ -15,7 +15,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh b/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh index 8d856005b9..7f967c6599 100755 --- a/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh +++ b/ccloud/fm-debezium-mysql-v2-source/fully-managed-debezium-v2-mysql.sh @@ -15,7 +15,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/ccloud/fm-debezium-postgresql-legacy-source/fully-managed-legacy-postgres.sh b/ccloud/fm-debezium-postgresql-legacy-source/fully-managed-legacy-postgres.sh index 2f73e0a7fb..579ae2c801 100755 --- a/ccloud/fm-debezium-postgresql-legacy-source/fully-managed-legacy-postgres.sh +++ b/ccloud/fm-debezium-postgresql-legacy-source/fully-managed-legacy-postgres.sh @@ -15,7 +15,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/ccloud/fm-debezium-postgresql-v2-source/fully-managed-v2-postgres.sh b/ccloud/fm-debezium-postgresql-v2-source/fully-managed-v2-postgres.sh index eb5f977207..ac1247b15b 100755 --- a/ccloud/fm-debezium-postgresql-v2-source/fully-managed-v2-postgres.sh +++ b/ccloud/fm-debezium-postgresql-v2-source/fully-managed-v2-postgres.sh @@ -15,7 +15,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source.sh b/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source.sh index f2d85456d6..9f9eaefc7e 100755 --- a/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source.sh +++ b/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source.sh @@ -16,7 +16,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source.sh b/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source.sh index 5ac87acda9..9da5de2b37 100755 --- a/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source.sh +++ b/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source.sh @@ -16,7 +16,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/ccloud/fm-gcp-bigquery-legacy-sink/fully-managed-gcp-bigquery-sink-legacy.sh b/ccloud/fm-gcp-bigquery-legacy-sink/fully-managed-gcp-bigquery-sink-legacy.sh index 1f29a0a956..fef87dd0f1 100755 --- a/ccloud/fm-gcp-bigquery-legacy-sink/fully-managed-gcp-bigquery-sink-legacy.sh +++ b/ccloud/fm-gcp-bigquery-legacy-sink/fully-managed-gcp-bigquery-sink-legacy.sh @@ -14,7 +14,7 @@ cd ../../ccloud/fm-gcp-bigquery-legacy-sink GCP_KEYFILE="${DIR}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/ccloud/fm-gcp-bigquery-v2-sink/fully-managed-gcp-bigquery-sink-v2.sh b/ccloud/fm-gcp-bigquery-v2-sink/fully-managed-gcp-bigquery-sink-v2.sh index 7927ffcfff..2a588eed61 100755 --- a/ccloud/fm-gcp-bigquery-v2-sink/fully-managed-gcp-bigquery-sink-v2.sh +++ b/ccloud/fm-gcp-bigquery-v2-sink/fully-managed-gcp-bigquery-sink-v2.sh @@ -14,7 +14,7 @@ cd ../../ccloud/fm-gcp-bigquery-v2-sink GCP_KEYFILE="${DIR}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh b/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh index 941f9c135e..8e9ffee294 100755 --- a/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh +++ b/ccloud/fm-gcp-bigtable-sink/fully-managed-gcp-bigtable-sink.sh @@ -17,7 +17,7 @@ cd ../../ccloud/fm-gcp-bigtable-sink GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/ccloud/fm-gcp-cloud-functions-gen2-sink/fully-managed-google-cloud-functions-gen2-sink.sh b/ccloud/fm-gcp-cloud-functions-gen2-sink/fully-managed-google-cloud-functions-gen2-sink.sh index 7750334d16..729f2ee2d5 100755 --- a/ccloud/fm-gcp-cloud-functions-gen2-sink/fully-managed-google-cloud-functions-gen2-sink.sh +++ b/ccloud/fm-gcp-cloud-functions-gen2-sink/fully-managed-google-cloud-functions-gen2-sink.sh @@ -16,7 +16,7 @@ cd ../../ccloud/fm-gcp-cloud-functions-gen2-sink GCP_KEYFILE="${DIR}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/ccloud/fm-gcp-cloud-functions-legacy-sink/fully-managed-google-cloud-functions-legacy-sink.sh b/ccloud/fm-gcp-cloud-functions-legacy-sink/fully-managed-google-cloud-functions-legacy-sink.sh index 5df1e6620d..6e2647b4f9 100755 --- a/ccloud/fm-gcp-cloud-functions-legacy-sink/fully-managed-google-cloud-functions-legacy-sink.sh +++ b/ccloud/fm-gcp-cloud-functions-legacy-sink/fully-managed-google-cloud-functions-legacy-sink.sh @@ -16,7 +16,7 @@ cd ../../ccloud/fm-gcp-cloud-functions-legacy-sink GCP_KEYFILE="${DIR}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/ccloud/fm-gcp-gcs-sink/fully-managed-gcs-sink.sh b/ccloud/fm-gcp-gcs-sink/fully-managed-gcs-sink.sh index 6722116608..02c4d72d80 100755 --- a/ccloud/fm-gcp-gcs-sink/fully-managed-gcs-sink.sh +++ b/ccloud/fm-gcp-gcs-sink/fully-managed-gcs-sink.sh @@ -14,7 +14,7 @@ cd ../../ccloud/fm-gcp-gcs-sink GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/ccloud/fm-gcp-gcs-source/fully-managed-gcs-source.sh b/ccloud/fm-gcp-gcs-source/fully-managed-gcs-source.sh index 6913a9d39a..0a66f26f3b 100755 --- a/ccloud/fm-gcp-gcs-source/fully-managed-gcs-source.sh +++ b/ccloud/fm-gcp-gcs-source/fully-managed-gcs-source.sh @@ -14,7 +14,7 @@ cd ../../ccloud/fm-gcp-gcs-source GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh b/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh index bcbe6bb428..7a63383094 100755 --- a/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh +++ b/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh @@ -14,7 +14,7 @@ cd ../../ccloud/fm-gcp-pubsub-source GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/ccloud/fm-gcp-spanner-sink/fully-managed-gcp-spanner-sink.sh b/ccloud/fm-gcp-spanner-sink/fully-managed-gcp-spanner-sink.sh index 5d65fc3d71..a259f3d84c 100755 --- a/ccloud/fm-gcp-spanner-sink/fully-managed-gcp-spanner-sink.sh +++ b/ccloud/fm-gcp-spanner-sink/fully-managed-gcp-spanner-sink.sh @@ -18,7 +18,7 @@ cd ../../ccloud/fm-gcp-spanner-sink GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/ccloud/fm-salesforce-cdc-source/fully-managed-salesforce-cdc-source-jwt-flow.sh b/ccloud/fm-salesforce-cdc-source/fully-managed-salesforce-cdc-source-jwt-flow.sh index ee04aa3002..bd7ed68226 100755 --- a/ccloud/fm-salesforce-cdc-source/fully-managed-salesforce-cdc-source-jwt-flow.sh +++ b/ccloud/fm-salesforce-cdc-source/fully-managed-salesforce-cdc-source-jwt-flow.sh @@ -50,7 +50,7 @@ fi if [ ! -f ${PWD}/salesforce-confluent.keystore.jks ] then # not running with github actions - logerror "ERROR: ${PWD}/salesforce-confluent.keystore.jks is missing. Check README !" + logerror "❌ ${PWD}/salesforce-confluent.keystore.jks is missing. Check README !" exit 1 fi diff --git a/ccloud/haproxy/start.sh b/ccloud/haproxy/start.sh index c7c4335646..c20ef64348 100755 --- a/ccloud/haproxy/start.sh +++ b/ccloud/haproxy/start.sh @@ -196,7 +196,7 @@ docker run confluentinc/cp-kafkacat:${TAG} kafkacat -b $PKC_ENDPOINT_WITH_PORT - nb_broker=$(docker run confluentinc/cp-kafkacat:${TAG} kafkacat -b $PKC_ENDPOINT_WITH_PORT -L -X security.protocol=SASL_SSL -X sasl.mechanisms=PLAIN -X sasl.username=$CLOUD_KEY -X sasl.password=$CLOUD_SECRET | grep "pkc" | grep " at " | wc -l) if [ $nb_broker -eq 0 ] then - logerror "ERROR: No broker could be discovered using Kafkacat" + logerror "❌ No broker could be discovered using Kafkacat" exit 1 fi diff --git a/ccloud/replicator/executable-onprem-to-cloud-avro.sh b/ccloud/replicator/executable-onprem-to-cloud-avro.sh index 36359ee244..23af4383a3 100755 --- a/ccloud/replicator/executable-onprem-to-cloud-avro.sh +++ b/ccloud/replicator/executable-onprem-to-cloud-avro.sh @@ -19,7 +19,7 @@ if [ -f ${DIR}/../../.ccloud/env.delta ] then source ${DIR}/../../.ccloud/env.delta else - logerror "ERROR: ${DIR}/../../.ccloud/env.delta has not been generated" + logerror "❌ ${DIR}/../../.ccloud/env.delta has not been generated" exit 1 fi diff --git a/ccloud/replicator/executable-onprem-to-cloud.sh b/ccloud/replicator/executable-onprem-to-cloud.sh index 5d10a5b14e..5aed7c0751 100755 --- a/ccloud/replicator/executable-onprem-to-cloud.sh +++ b/ccloud/replicator/executable-onprem-to-cloud.sh @@ -19,7 +19,7 @@ if [ -f ${DIR}/../../.ccloud/env.delta ] then source ${DIR}/../../.ccloud/env.delta else - logerror "ERROR: ${DIR}/../../.ccloud/env.delta has not been generated" + logerror "❌ ${DIR}/../../.ccloud/env.delta has not been generated" exit 1 fi diff --git a/connect/connect-amps-source/amps-source.sh b/connect/connect-amps-source/amps-source.sh index d45501d551..efe2598fce 100755 --- a/connect/connect-amps-source/amps-source.sh +++ b/connect/connect-amps-source/amps-source.sh @@ -12,7 +12,7 @@ cd - if [ ! -f ${DIR}/docker-amps/AMPS.tar.gz ] then - logerror "ERROR: ${DIR}/docker-amps/ does not contain AMPS tgz file AMPS.tar.gz" + logerror "❌ ${DIR}/docker-amps/ does not contain AMPS tgz file AMPS.tar.gz" exit 1 fi diff --git a/connect/connect-appdynamics-metrics-sink/appdynamics-metrics-sink.sh b/connect/connect-appdynamics-metrics-sink/appdynamics-metrics-sink.sh index 14d03b63ff..e64024648d 100755 --- a/connect/connect-appdynamics-metrics-sink/appdynamics-metrics-sink.sh +++ b/connect/connect-appdynamics-metrics-sink/appdynamics-metrics-sink.sh @@ -8,7 +8,7 @@ source ${DIR}/../../scripts/utils.sh if [ ! -f ${DIR}/docker-appdynamics-metrics/machine-agent.zip ] then - logerror "ERROR: ${DIR}/docker-appdynamics-metrics/ does not contain file machine-agent.zip" + logerror "❌ ${DIR}/docker-appdynamics-metrics/ does not contain file machine-agent.zip" exit 1 fi diff --git a/connect/connect-aws-cloudwatch-logs-source/cloudwatch-with-assuming-iam-role.sh b/connect/connect-aws-cloudwatch-logs-source/cloudwatch-with-assuming-iam-role.sh index 9c32bda130..c7e4ef637d 100755 --- a/connect/connect-aws-cloudwatch-logs-source/cloudwatch-with-assuming-iam-role.sh +++ b/connect/connect-aws-cloudwatch-logs-source/cloudwatch-with-assuming-iam-role.sh @@ -7,7 +7,7 @@ source ${DIR}/../../scripts/utils.sh export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" + logerror "❌ $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi diff --git a/connect/connect-aws-cloudwatch-metrics-sink/cloudwatch-metrics-sink-with-assuming-iam-role.sh b/connect/connect-aws-cloudwatch-metrics-sink/cloudwatch-metrics-sink-with-assuming-iam-role.sh index 80d1f74f81..575d82ca34 100644 --- a/connect/connect-aws-cloudwatch-metrics-sink/cloudwatch-metrics-sink-with-assuming-iam-role.sh +++ b/connect/connect-aws-cloudwatch-metrics-sink/cloudwatch-metrics-sink-with-assuming-iam-role.sh @@ -7,7 +7,7 @@ source ${DIR}/../../scripts/utils.sh export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" + logerror "❌ $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi diff --git a/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-assuming-iam-role.sh b/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-assuming-iam-role.sh index 97914ee687..e07e631d93 100755 --- a/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-assuming-iam-role.sh +++ b/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-assuming-iam-role.sh @@ -13,7 +13,7 @@ fi export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" + logerror "❌ $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi diff --git a/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-custom-basic-aws-credentials-provider.sh b/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-custom-basic-aws-credentials-provider.sh index 2d07a8278a..ed78aefb2c 100755 --- a/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-custom-basic-aws-credentials-provider.sh +++ b/connect/connect-aws-dynamodb-sink/dynamodb-sink-with-custom-basic-aws-credentials-provider.sh @@ -19,7 +19,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-aws-kinesis-source/kinesis-source-assuming-iam-role-with-custom-awscredentialsprovider.sh b/connect/connect-aws-kinesis-source/kinesis-source-assuming-iam-role-with-custom-awscredentialsprovider.sh index c00d597a2f..9ae3426fa2 100755 --- a/connect/connect-aws-kinesis-source/kinesis-source-assuming-iam-role-with-custom-awscredentialsprovider.sh +++ b/connect/connect-aws-kinesis-source/kinesis-source-assuming-iam-role-with-custom-awscredentialsprovider.sh @@ -41,7 +41,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-aws-kinesis-source/kinesis-source-with-assuming-iam-role.sh b/connect/connect-aws-kinesis-source/kinesis-source-with-assuming-iam-role.sh index c5ca7c85ab..b4f183c3cc 100755 --- a/connect/connect-aws-kinesis-source/kinesis-source-with-assuming-iam-role.sh +++ b/connect/connect-aws-kinesis-source/kinesis-source-with-assuming-iam-role.sh @@ -13,7 +13,7 @@ fi export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" + logerror "❌ $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi diff --git a/connect/connect-aws-lambda-sink/lambda-sink-assuming-iam-role-with-custom-aws-credential-provider.sh b/connect/connect-aws-lambda-sink/lambda-sink-assuming-iam-role-with-custom-aws-credential-provider.sh index 9c834bbc97..e9c8355357 100755 --- a/connect/connect-aws-lambda-sink/lambda-sink-assuming-iam-role-with-custom-aws-credential-provider.sh +++ b/connect/connect-aws-lambda-sink/lambda-sink-assuming-iam-role-with-custom-aws-credential-provider.sh @@ -33,7 +33,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-aws-lambda-sink/lambda-sink-with-assuming-iam-role.sh b/connect/connect-aws-lambda-sink/lambda-sink-with-assuming-iam-role.sh index 1f5013d2e2..4f4f90f8bd 100755 --- a/connect/connect-aws-lambda-sink/lambda-sink-with-assuming-iam-role.sh +++ b/connect/connect-aws-lambda-sink/lambda-sink-with-assuming-iam-role.sh @@ -7,7 +7,7 @@ source ${DIR}/../../scripts/utils.sh export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" + logerror "❌ $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi diff --git a/connect/connect-aws-redshift-sink/redshift-sink-with-assuming-iam-role.sh b/connect/connect-aws-redshift-sink/redshift-sink-with-assuming-iam-role.sh index 225d8a45b6..7fb276a3e2 100755 --- a/connect/connect-aws-redshift-sink/redshift-sink-with-assuming-iam-role.sh +++ b/connect/connect-aws-redshift-sink/redshift-sink-with-assuming-iam-role.sh @@ -7,7 +7,7 @@ source ${DIR}/../../scripts/utils.sh export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" + logerror "❌ $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi diff --git a/connect/connect-aws-s3-sink/s3-sink-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh b/connect/connect-aws-s3-sink/s3-sink-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh index c59c21ca74..e4b0df387a 100755 --- a/connect/connect-aws-s3-sink/s3-sink-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh +++ b/connect/connect-aws-s3-sink/s3-sink-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh @@ -39,7 +39,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-aws-s3-sink/s3-sink-proxy-with-assuming-iam-role.sh b/connect/connect-aws-s3-sink/s3-sink-proxy-with-assuming-iam-role.sh index 7a3ade1cf0..f31f3bbce5 100755 --- a/connect/connect-aws-s3-sink/s3-sink-proxy-with-assuming-iam-role.sh +++ b/connect/connect-aws-s3-sink/s3-sink-proxy-with-assuming-iam-role.sh @@ -11,7 +11,7 @@ exit 111 export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" + logerror "❌ $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi diff --git a/connect/connect-aws-s3-sink/s3-sink-with-assuming-iam-role.sh b/connect/connect-aws-s3-sink/s3-sink-with-assuming-iam-role.sh index 3418a99572..04d6fd4a33 100755 --- a/connect/connect-aws-s3-sink/s3-sink-with-assuming-iam-role.sh +++ b/connect/connect-aws-s3-sink/s3-sink-with-assuming-iam-role.sh @@ -7,7 +7,7 @@ source ${DIR}/../../scripts/utils.sh export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" + logerror "❌ $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi diff --git a/connect/connect-aws-s3-source/s3-source-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh b/connect/connect-aws-s3-source/s3-source-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh index 4796634964..62600dcf19 100755 --- a/connect/connect-aws-s3-source/s3-source-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh +++ b/connect/connect-aws-s3-source/s3-source-backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.sh @@ -43,7 +43,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role.sh b/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role.sh index 71cb86ceca..3813c21f30 100755 --- a/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role.sh +++ b/connect/connect-aws-s3-source/s3-source-backup-and-restore-with-assuming-iam-role.sh @@ -13,7 +13,7 @@ fi export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" + logerror "❌ $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi diff --git a/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh b/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh index 708f6361aa..7892ea7ad9 100755 --- a/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh +++ b/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh @@ -45,7 +45,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh b/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh index 9fb83bc3fc..910bd771aa 100755 --- a/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh +++ b/connect/connect-aws-sqs-source/sqs-source-with-assuming-iam-role.sh @@ -7,7 +7,7 @@ source ${DIR}/../../scripts/utils.sh export AWS_CREDENTIALS_FILE_NAME=$HOME/.aws/credentials-with-assuming-iam-role if [ ! -f $AWS_CREDENTIALS_FILE_NAME ] then - logerror "ERROR: $AWS_CREDENTIALS_FILE_NAME is not set" + logerror "❌ $AWS_CREDENTIALS_FILE_NAME is not set" exit 1 fi diff --git a/connect/connect-azure-event-hubs-source/azure-event-hubs-source.sh b/connect/connect-azure-event-hubs-source/azure-event-hubs-source.sh index 90865c92dd..ff9e6bb9f4 100755 --- a/connect/connect-azure-event-hubs-source/azure-event-hubs-source.sh +++ b/connect/connect-azure-event-hubs-source/azure-event-hubs-source.sh @@ -12,7 +12,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-azure-service-bus-source/azure-service-bus-source.sh b/connect/connect-azure-service-bus-source/azure-service-bus-source.sh index 0854b8d73d..83ce91d55d 100755 --- a/connect/connect-azure-service-bus-source/azure-service-bus-source.sh +++ b/connect/connect-azure-service-bus-source/azure-service-bus-source.sh @@ -13,7 +13,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-cdc-oracle11-source/cdc-oracle11-source.sh b/connect/connect-cdc-oracle11-source/cdc-oracle11-source.sh index f015764834..f7667f6621 100755 --- a/connect/connect-cdc-oracle11-source/cdc-oracle11-source.sh +++ b/connect/connect-cdc-oracle11-source/cdc-oracle11-source.sh @@ -15,7 +15,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table.sh index fc02f608a1..3f5c7c4808 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table.sh @@ -17,7 +17,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table.sh index b8aac0593b..502c9b4358 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table.sh @@ -21,7 +21,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table.sh index 314ba9f34f..6f50fbd1c7 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table.sh @@ -17,7 +17,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table.sh index 6ffd313379..39a18cbba6 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table.sh @@ -23,7 +23,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh index 534b4cf991..b3d9c41893 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh @@ -17,7 +17,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh index 0aa1edf7ef..a40952c4fa 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh @@ -23,7 +23,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh index 38624f5cf3..03309ef67f 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh @@ -17,7 +17,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table.sh index 93a2a70b55..fa29593e64 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table.sh @@ -23,7 +23,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-couchbase-sink/couchbase-sink.sh b/connect/connect-couchbase-sink/couchbase-sink.sh index 87f9d00f59..3d78ea8529 100755 --- a/connect/connect-couchbase-sink/couchbase-sink.sh +++ b/connect/connect-couchbase-sink/couchbase-sink.sh @@ -11,7 +11,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-debezium-mysql-source/debezium-mysql-source.sh b/connect/connect-debezium-mysql-source/debezium-mysql-source.sh index 74f39e28f4..e6a2f1a3d8 100755 --- a/connect/connect-debezium-mysql-source/debezium-mysql-source.sh +++ b/connect/connect-debezium-mysql-source/debezium-mysql-source.sh @@ -21,7 +21,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-debezium-oracle19-source/debezium-oracle19.sh b/connect/connect-debezium-oracle19-source/debezium-oracle19.sh index 925c971dbd..06837fd014 100755 --- a/connect/connect-debezium-oracle19-source/debezium-oracle19.sh +++ b/connect/connect-debezium-oracle19-source/debezium-oracle19.sh @@ -17,7 +17,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi @@ -47,7 +47,7 @@ cd ../../connect/connect-debezium-oracle19-source get_3rdparty_file "ojdbc8.jar" if [ ! -f ${PWD}/ojdbc8.jar ] then - logerror "ERROR: ${PWD}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" + logerror "❌ ${PWD}/ojdbc8.jar is missing. It must be downloaded manually in order to acknowledge user agreement" exit 1 fi cd - diff --git a/connect/connect-debezium-postgresql-source/debezium-postgres-source.sh b/connect/connect-debezium-postgresql-source/debezium-postgres-source.sh index 852f35b305..4ce57bfa5c 100755 --- a/connect/connect-debezium-postgresql-source/debezium-postgres-source.sh +++ b/connect/connect-debezium-postgresql-source/debezium-postgres-source.sh @@ -21,7 +21,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source.sh b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source.sh index ce54b222b4..884234661e 100755 --- a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source.sh +++ b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source.sh @@ -21,7 +21,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-gcp-bigquery-sink/gcp-bigquery-sink.sh b/connect/connect-gcp-bigquery-sink/gcp-bigquery-sink.sh index 45cfeafe7f..4923cd07c1 100755 --- a/connect/connect-gcp-bigquery-sink/gcp-bigquery-sink.sh +++ b/connect/connect-gcp-bigquery-sink/gcp-bigquery-sink.sh @@ -14,7 +14,7 @@ cd ../../connect/connect-gcp-bigquery-sink GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh index 1a7671f6c0..30bfeb396c 100755 --- a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh +++ b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink-proxy.sh @@ -17,7 +17,7 @@ cd ../../connect/connect-gcp-bigtable-sink GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh index 471a8b9ac3..409da39f82 100755 --- a/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh +++ b/connect/connect-gcp-bigtable-sink/gcp-bigtable-sink.sh @@ -17,7 +17,7 @@ cd ../../connect/connect-gcp-bigtable-sink GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-gcp-cloud-functions-sink/google-cloud-functions-sink.sh b/connect/connect-gcp-cloud-functions-sink/google-cloud-functions-sink.sh index d6fd25468c..dafa0d6758 100755 --- a/connect/connect-gcp-cloud-functions-sink/google-cloud-functions-sink.sh +++ b/connect/connect-gcp-cloud-functions-sink/google-cloud-functions-sink.sh @@ -16,7 +16,7 @@ cd ../../connect/connect-gcp-cloud-functions-sink GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-gcp-dataproc-sink/gcp-dataproc-sink.sh b/connect/connect-gcp-dataproc-sink/gcp-dataproc-sink.sh index d0a6e70d41..30d5cadacd 100755 --- a/connect/connect-gcp-dataproc-sink/gcp-dataproc-sink.sh +++ b/connect/connect-gcp-dataproc-sink/gcp-dataproc-sink.sh @@ -13,7 +13,7 @@ cd ../../connect/connect-gcp-cloud-functions-sink GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-gcp-firebase-sink/gcp-firebase-sink.sh b/connect/connect-gcp-firebase-sink/gcp-firebase-sink.sh index 5beabe55d3..b04bacd564 100755 --- a/connect/connect-gcp-firebase-sink/gcp-firebase-sink.sh +++ b/connect/connect-gcp-firebase-sink/gcp-firebase-sink.sh @@ -13,7 +13,7 @@ cd ../../connect/connect-gcp-firebase-sink GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-gcp-firebase-source/gcp-firebase-source.sh b/connect/connect-gcp-firebase-source/gcp-firebase-source.sh index 25423ff87e..cd2dfaa8c2 100755 --- a/connect/connect-gcp-firebase-source/gcp-firebase-source.sh +++ b/connect/connect-gcp-firebase-source/gcp-firebase-source.sh @@ -13,7 +13,7 @@ cd ../../connect/connect-gcp-firebase-source GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-gcp-gcs-sink/gcs-sink.sh b/connect/connect-gcp-gcs-sink/gcs-sink.sh index 56100b0747..5b11b6a5d5 100755 --- a/connect/connect-gcp-gcs-sink/gcs-sink.sh +++ b/connect/connect-gcp-gcs-sink/gcs-sink.sh @@ -14,7 +14,7 @@ cd ../../connect/connect-gcp-gcs-sink GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-gcp-gcs-source/gcs-source-backup-and-restore.sh b/connect/connect-gcp-gcs-source/gcs-source-backup-and-restore.sh index 07c74c3341..3d23fd4bac 100755 --- a/connect/connect-gcp-gcs-source/gcs-source-backup-and-restore.sh +++ b/connect/connect-gcp-gcs-source/gcs-source-backup-and-restore.sh @@ -20,7 +20,7 @@ cd ../../connect/connect-gcp-gcs-source GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-gcp-gcs-source/gcs-source-generalized.sh b/connect/connect-gcp-gcs-source/gcs-source-generalized.sh index a6986269c6..4caf9cdac9 100755 --- a/connect/connect-gcp-gcs-source/gcs-source-generalized.sh +++ b/connect/connect-gcp-gcs-source/gcs-source-generalized.sh @@ -26,7 +26,7 @@ cd ../../connect/connect-gcp-gcs-source GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh b/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh index 43eaef97c5..127dcb1e03 100755 --- a/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh +++ b/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh @@ -30,7 +30,7 @@ fi GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh b/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh index 07e04923d0..e8894117d4 100755 --- a/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh +++ b/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh @@ -30,7 +30,7 @@ fi GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh b/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh index 17e7ffe8c3..752fbb054b 100755 --- a/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh +++ b/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh @@ -20,7 +20,7 @@ cd ../../connect/connect-gcp-pubsub-source GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh b/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh index 9e6ff18f05..b0d7638bbc 100755 --- a/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh +++ b/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh @@ -14,7 +14,7 @@ cd ../../connect/connect-gcp-pubsub-source GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-gcp-spanner-sink/gcp-spanner-sink-proxy.sh b/connect/connect-gcp-spanner-sink/gcp-spanner-sink-proxy.sh index bce6c15586..aa5d41f0aa 100755 --- a/connect/connect-gcp-spanner-sink/gcp-spanner-sink-proxy.sh +++ b/connect/connect-gcp-spanner-sink/gcp-spanner-sink-proxy.sh @@ -21,7 +21,7 @@ cd ../../connect/connect-gcp-spanner-sink GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-gcp-spanner-sink/gcp-spanner-sink.sh b/connect/connect-gcp-spanner-sink/gcp-spanner-sink.sh index dfa2acc12b..14f990928c 100755 --- a/connect/connect-gcp-spanner-sink/gcp-spanner-sink.sh +++ b/connect/connect-gcp-spanner-sink/gcp-spanner-sink.sh @@ -18,7 +18,7 @@ cd ../../connect/connect-gcp-spanner-sink GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-graphdb-sink/graphdb-sink.sh b/connect/connect-graphdb-sink/graphdb-sink.sh index d860ec9408..b54a67afab 100755 --- a/connect/connect-graphdb-sink/graphdb-sink.sh +++ b/connect/connect-graphdb-sink/graphdb-sink.sh @@ -13,7 +13,7 @@ get_3rdparty_file "$GRAPHDB_SINK_CONNECTOR_ZIP" if [ ! -f ${PWD}/$GRAPHDB_SINK_CONNECTOR_ZIP ] then - logerror "ERROR: ${PWD}/$GRAPHDB_SINK_CONNECTOR_ZIP is missing. You must be a Confluent Employee to run this example !" + logerror "❌ ${PWD}/$GRAPHDB_SINK_CONNECTOR_ZIP is missing. You must be a Confluent Employee to run this example !" exit 1 fi diff --git a/connect/connect-ibm-mq-sink/ibm-mq-sink-mtls.sh b/connect/connect-ibm-mq-sink/ibm-mq-sink-mtls.sh index 503dd3c506..6819cb23ab 100755 --- a/connect/connect-ibm-mq-sink/ibm-mq-sink-mtls.sh +++ b/connect/connect-ibm-mq-sink/ibm-mq-sink-mtls.sh @@ -10,7 +10,7 @@ get_3rdparty_file "IBM-MQ-Install-Java-All.jar" if [ ! -f ${PWD}/IBM-MQ-Install-Java-All.jar ] then # not running with github actions - logerror "ERROR: ${PWD}/IBM-MQ-Install-Java-All.jar is missing. It must be downloaded manually in order to acknowledge user agreement" + logerror "❌ ${PWD}/IBM-MQ-Install-Java-All.jar is missing. It must be downloaded manually in order to acknowledge user agreement" exit 1 fi diff --git a/connect/connect-ibm-mq-sink/ibm-mq-sink-ssl.sh b/connect/connect-ibm-mq-sink/ibm-mq-sink-ssl.sh index 9173a974ef..4c6c419309 100755 --- a/connect/connect-ibm-mq-sink/ibm-mq-sink-ssl.sh +++ b/connect/connect-ibm-mq-sink/ibm-mq-sink-ssl.sh @@ -10,7 +10,7 @@ get_3rdparty_file "IBM-MQ-Install-Java-All.jar" if [ ! -f ${PWD}/IBM-MQ-Install-Java-All.jar ] then # not running with github actions - logerror "ERROR: ${PWD}/IBM-MQ-Install-Java-All.jar is missing. It must be downloaded manually in order to acknowledge user agreement" + logerror "❌ ${PWD}/IBM-MQ-Install-Java-All.jar is missing. It must be downloaded manually in order to acknowledge user agreement" exit 1 fi diff --git a/connect/connect-ibm-mq-sink/ibm-mq-sink.sh b/connect/connect-ibm-mq-sink/ibm-mq-sink.sh index 65c794c914..39628f7b14 100755 --- a/connect/connect-ibm-mq-sink/ibm-mq-sink.sh +++ b/connect/connect-ibm-mq-sink/ibm-mq-sink.sh @@ -10,7 +10,7 @@ get_3rdparty_file "IBM-MQ-Install-Java-All.jar" if [ ! -f ${PWD}/IBM-MQ-Install-Java-All.jar ] then # not running with github actions - logerror "ERROR: ${PWD}/IBM-MQ-Install-Java-All.jar is missing. It must be downloaded manually in order to acknowledge user agreement" + logerror "❌ ${PWD}/IBM-MQ-Install-Java-All.jar is missing. It must be downloaded manually in order to acknowledge user agreement" exit 1 fi diff --git a/connect/connect-ibm-mq-source/ibm-mq-mtls.sh b/connect/connect-ibm-mq-source/ibm-mq-mtls.sh index e23c823185..6192d922c7 100755 --- a/connect/connect-ibm-mq-source/ibm-mq-mtls.sh +++ b/connect/connect-ibm-mq-source/ibm-mq-mtls.sh @@ -10,7 +10,7 @@ get_3rdparty_file "IBM-MQ-Install-Java-All.jar" if [ ! -f ${PWD}/IBM-MQ-Install-Java-All.jar ] then # not running with github actions - logerror "ERROR: ${PWD}/IBM-MQ-Install-Java-All.jar is missing. It must be downloaded manually in order to acknowledge user agreement" + logerror "❌ ${PWD}/IBM-MQ-Install-Java-All.jar is missing. It must be downloaded manually in order to acknowledge user agreement" exit 1 fi diff --git a/connect/connect-ibm-mq-source/ibm-mq-ssl.sh b/connect/connect-ibm-mq-source/ibm-mq-ssl.sh index 5c1671386c..be656741f9 100755 --- a/connect/connect-ibm-mq-source/ibm-mq-ssl.sh +++ b/connect/connect-ibm-mq-source/ibm-mq-ssl.sh @@ -10,7 +10,7 @@ get_3rdparty_file "IBM-MQ-Install-Java-All.jar" if [ ! -f ${PWD}/IBM-MQ-Install-Java-All.jar ] then # not running with github actions - logerror "ERROR: ${PWD}/IBM-MQ-Install-Java-All.jar is missing. It must be downloaded manually in order to acknowledge user agreement" + logerror "❌ ${PWD}/IBM-MQ-Install-Java-All.jar is missing. It must be downloaded manually in order to acknowledge user agreement" exit 1 fi diff --git a/connect/connect-ibm-mq-source/ibm-mq.sh b/connect/connect-ibm-mq-source/ibm-mq.sh index d66e7a49be..369f267963 100755 --- a/connect/connect-ibm-mq-source/ibm-mq.sh +++ b/connect/connect-ibm-mq-source/ibm-mq.sh @@ -10,7 +10,7 @@ get_3rdparty_file "IBM-MQ-Install-Java-All.jar" if [ ! -f ${PWD}/IBM-MQ-Install-Java-All.jar ] then # not running with github actions - logerror "ERROR: ${PWD}/IBM-MQ-Install-Java-All.jar is missing. It must be downloaded manually in order to acknowledge user agreement" + logerror "❌ ${PWD}/IBM-MQ-Install-Java-All.jar is missing. It must be downloaded manually in order to acknowledge user agreement" exit 1 fi diff --git a/connect/connect-jdbc-aws-athena-source/athena-jdbc-source.sh b/connect/connect-jdbc-aws-athena-source/athena-jdbc-source.sh index 41c63a7bb5..f9b94b3199 100755 --- a/connect/connect-jdbc-aws-athena-source/athena-jdbc-source.sh +++ b/connect/connect-jdbc-aws-athena-source/athena-jdbc-source.sh @@ -13,7 +13,7 @@ cd - if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" + logerror "❌ either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" exit 1 else if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] @@ -34,7 +34,7 @@ else AWS_REGION=$(aws configure get region | tr '\r' '\n') if [ "$AWS_REGION" == "" ] then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" + logerror "❌ either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" exit 1 fi fi diff --git a/connect/connect-jdbc-gcp-bigquery-source/jdbc-gcp-bigquery-source.sh b/connect/connect-jdbc-gcp-bigquery-source/jdbc-gcp-bigquery-source.sh index 1f1adb7a09..8e08ed9047 100755 --- a/connect/connect-jdbc-gcp-bigquery-source/jdbc-gcp-bigquery-source.sh +++ b/connect/connect-jdbc-gcp-bigquery-source/jdbc-gcp-bigquery-source.sh @@ -23,7 +23,7 @@ cd ../../connect/connect-jdbc-gcp-bigquery-source GCP_KEYFILE="${PWD}/keyfile.json" if [ ! -f ${GCP_KEYFILE} ] && [ -z "$GCP_KEYFILE_CONTENT" ] then - logerror "ERROR: either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" + logerror "❌ either the file ${GCP_KEYFILE} is not present or environment variable GCP_KEYFILE_CONTENT is not set!" exit 1 else if [ -f ${GCP_KEYFILE} ] diff --git a/connect/connect-jdbc-mysql-source/mysql.sh b/connect/connect-jdbc-mysql-source/mysql.sh index d635c508c3..745a88c0ca 100755 --- a/connect/connect-jdbc-mysql-source/mysql.sh +++ b/connect/connect-jdbc-mysql-source/mysql.sh @@ -23,7 +23,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-jdbc-oracle11-source/oracle11.sh b/connect/connect-jdbc-oracle11-source/oracle11.sh index db6795493d..175677bfb5 100755 --- a/connect/connect-jdbc-oracle11-source/oracle11.sh +++ b/connect/connect-jdbc-oracle11-source/oracle11.sh @@ -15,7 +15,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-jdbc-oracle12-source/oracle12.sh b/connect/connect-jdbc-oracle12-source/oracle12.sh index df0e9e3d6d..5629d8bac5 100755 --- a/connect/connect-jdbc-oracle12-source/oracle12.sh +++ b/connect/connect-jdbc-oracle12-source/oracle12.sh @@ -17,7 +17,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-jdbc-oracle19-source/oracle19.sh b/connect/connect-jdbc-oracle19-source/oracle19.sh index 9153996487..857b0c656e 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19.sh @@ -17,7 +17,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-jdbc-oracle21-source/oracle21.sh b/connect/connect-jdbc-oracle21-source/oracle21.sh index 3ac1feb68d..bac90432ef 100755 --- a/connect/connect-jdbc-oracle21-source/oracle21.sh +++ b/connect/connect-jdbc-oracle21-source/oracle21.sh @@ -17,7 +17,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-jdbc-postgresql-source/postgres.sh b/connect/connect-jdbc-postgresql-source/postgres.sh index a163afa645..9338fe23d6 100755 --- a/connect/connect-jdbc-postgresql-source/postgres.sh +++ b/connect/connect-jdbc-postgresql-source/postgres.sh @@ -15,7 +15,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-jdbc-sqlserver-source/sqlserver-jtds.sh b/connect/connect-jdbc-sqlserver-source/sqlserver-jtds.sh index 647cf948de..678c14d0de 100755 --- a/connect/connect-jdbc-sqlserver-source/sqlserver-jtds.sh +++ b/connect/connect-jdbc-sqlserver-source/sqlserver-jtds.sh @@ -15,7 +15,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft.sh b/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft.sh index b2e1ce7876..ff7e826a66 100755 --- a/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft.sh +++ b/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft.sh @@ -25,7 +25,7 @@ then docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-jms-tibco-sink/jms-tibco-ems-sink.sh b/connect/connect-jms-tibco-sink/jms-tibco-ems-sink.sh index 0564815599..6c519b996d 100755 --- a/connect/connect-jms-tibco-sink/jms-tibco-ems-sink.sh +++ b/connect/connect-jms-tibco-sink/jms-tibco-ems-sink.sh @@ -10,7 +10,7 @@ get_3rdparty_file "TIB_ems-ce_8.5.1_linux_x86_64.zip" cd - if [ ! -f ../../connect/connect-jms-tibco-sink/docker-tibco/TIB_ems-ce_8.5.1_linux_x86_64.zip ] then - logerror "ERROR: ../../connect/connect-jms-tibco-sink/docker-tibco/ does not contain TIBCO EMS zip file TIB_ems-ce_8.5.1_linux_x86_64.zip" + logerror "❌ ../../connect/connect-jms-tibco-sink/docker-tibco/ does not contain TIBCO EMS zip file TIB_ems-ce_8.5.1_linux_x86_64.zip" exit 1 fi diff --git a/connect/connect-jms-tibco-source/jms-tibco.sh b/connect/connect-jms-tibco-source/jms-tibco.sh index fac0838424..1ffcdceffe 100755 --- a/connect/connect-jms-tibco-source/jms-tibco.sh +++ b/connect/connect-jms-tibco-source/jms-tibco.sh @@ -10,7 +10,7 @@ get_3rdparty_file "TIB_ems-ce_8.5.1_linux_x86_64.zip" cd - if [ ! -f ../../connect/connect-jms-tibco-source/docker-tibco/TIB_ems-ce_8.5.1_linux_x86_64.zip ] then - logerror "ERROR: ../../connect/connect-jms-tibco-source/docker-tibco/ does not contain TIBCO EMS zip file TIB_ems-ce_8.5.1_linux_x86_64.zip" + logerror "❌ ../../connect/connect-jms-tibco-source/docker-tibco/ does not contain TIBCO EMS zip file TIB_ems-ce_8.5.1_linux_x86_64.zip" exit 1 fi diff --git a/connect/connect-jms-weblogic-sink/jms-weblogic-sink.sh b/connect/connect-jms-weblogic-sink/jms-weblogic-sink.sh index cf6f65d082..8043144a6d 100755 --- a/connect/connect-jms-weblogic-sink/jms-weblogic-sink.sh +++ b/connect/connect-jms-weblogic-sink/jms-weblogic-sink.sh @@ -44,7 +44,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-jms-weblogic-source/jms-weblogic-source.sh b/connect/connect-jms-weblogic-source/jms-weblogic-source.sh index a4337ab9a8..ae4276fc51 100755 --- a/connect/connect-jms-weblogic-source/jms-weblogic-source.sh +++ b/connect/connect-jms-weblogic-source/jms-weblogic-source.sh @@ -44,7 +44,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-kudu-sink/kudu-sink.sh b/connect/connect-kudu-sink/kudu-sink.sh index 995a050259..455ee53a41 100755 --- a/connect/connect-kudu-sink/kudu-sink.sh +++ b/connect/connect-kudu-sink/kudu-sink.sh @@ -8,7 +8,7 @@ get_3rdparty_file "ImpalaJDBC42.jar" if [ ! -f ${DIR}/ImpalaJDBC42.jar ] then - logerror "ERROR: ${DIR}/ImpalaJDBC42.jar is missing. It must be downloaded manually in order to acknowledge user agreement" + logerror "❌ ${DIR}/ImpalaJDBC42.jar is missing. It must be downloaded manually in order to acknowledge user agreement" exit 1 fi diff --git a/connect/connect-kudu-source/kudu-source.sh b/connect/connect-kudu-source/kudu-source.sh index 794cdfb0ae..ef01054260 100755 --- a/connect/connect-kudu-source/kudu-source.sh +++ b/connect/connect-kudu-source/kudu-source.sh @@ -8,7 +8,7 @@ get_3rdparty_file "ImpalaJDBC42.jar" if [ ! -f ${DIR}/ImpalaJDBC42.jar ] then - logerror "ERROR: ${DIR}/ImpalaJDBC42.jar is missing. It must be downloaded manually in order to acknowledge user agreement" + logerror "❌ ${DIR}/ImpalaJDBC42.jar is missing. It must be downloaded manually in order to acknowledge user agreement" exit 1 fi diff --git a/connect/connect-pivotal-gemfire-sink/pivotal-gemfire-sink.sh b/connect/connect-pivotal-gemfire-sink/pivotal-gemfire-sink.sh index adee00e9af..33894d9449 100755 --- a/connect/connect-pivotal-gemfire-sink/pivotal-gemfire-sink.sh +++ b/connect/connect-pivotal-gemfire-sink/pivotal-gemfire-sink.sh @@ -13,7 +13,7 @@ then if [ ! -f ${DIR}/docker-pivotal-gemfire/pivotal-gemfire.tgz ] then - logerror "ERROR: ${DIR}/docker-pivotal-gemfire/ does not contain file pivotal-gemfire.tgz" + logerror "❌ ${DIR}/docker-pivotal-gemfire/ does not contain file pivotal-gemfire.tgz" exit 1 fi log "Building pivotal-gemfire docker image..it can take a while..." diff --git a/connect/connect-salesforce-cdc-source/salesforce-cdc-source-jwt-flow.sh b/connect/connect-salesforce-cdc-source/salesforce-cdc-source-jwt-flow.sh index 52e21fa78b..7cc014ef18 100755 --- a/connect/connect-salesforce-cdc-source/salesforce-cdc-source-jwt-flow.sh +++ b/connect/connect-salesforce-cdc-source/salesforce-cdc-source-jwt-flow.sh @@ -56,7 +56,7 @@ fi if [ ! -f ${PWD}/salesforce-confluent.keystore.jks ] then # not running with github actions - logerror "ERROR: ${PWD}/salesforce-confluent.keystore.jks is missing. Check README !" + logerror "❌ ${PWD}/salesforce-confluent.keystore.jks is missing. Check README !" exit 1 fi diff --git a/connect/connect-sap-hana-sink/sap-hana-sink.sh b/connect/connect-sap-hana-sink/sap-hana-sink.sh index 62ada8db03..10f09d8ce8 100755 --- a/connect/connect-sap-hana-sink/sap-hana-sink.sh +++ b/connect/connect-sap-hana-sink/sap-hana-sink.sh @@ -26,7 +26,7 @@ then docker run -i --rm -v "${DIR}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "${DIR}/${component}/modules/scala_2.13/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn install -DskipTests > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-tibco-sink/tibco-ems-sink.sh b/connect/connect-tibco-sink/tibco-ems-sink.sh index 3b1e21fb48..e430d85644 100755 --- a/connect/connect-tibco-sink/tibco-ems-sink.sh +++ b/connect/connect-tibco-sink/tibco-ems-sink.sh @@ -10,7 +10,7 @@ get_3rdparty_file "TIB_ems-ce_8.5.1_linux_x86_64.zip" cd - if [ ! -f ../../connect/connect-tibco-sink/docker-tibco/TIB_ems-ce_8.5.1_linux_x86_64.zip ] then - logerror "ERROR: ../../connect/connect-tibco-sink/docker-tibco/ does not contain TIBCO EMS zip file TIB_ems-ce_8.5.1_linux_x86_64.zip" + logerror "❌ ../../connect/connect-tibco-sink/docker-tibco/ does not contain TIBCO EMS zip file TIB_ems-ce_8.5.1_linux_x86_64.zip" exit 1 fi diff --git a/connect/connect-tibco-source/tibco-ems.sh b/connect/connect-tibco-source/tibco-ems.sh index 62801dc7a3..17beb9378b 100755 --- a/connect/connect-tibco-source/tibco-ems.sh +++ b/connect/connect-tibco-source/tibco-ems.sh @@ -10,7 +10,7 @@ get_3rdparty_file "TIB_ems-ce_8.5.1_linux_x86_64.zip" cd - if [ ! -f ../../connect/connect-tibco-source/docker-tibco/TIB_ems-ce_8.5.1_linux_x86_64.zip ] then - logerror "ERROR: ../../connect/connect-tibco-source/docker-tibco/ does not contain TIBCO EMS zip file TIB_ems-ce_8.5.1_linux_x86_64.zip" + logerror "❌ ../../connect/connect-tibco-source/docker-tibco/ does not contain TIBCO EMS zip file TIB_ems-ce_8.5.1_linux_x86_64.zip" exit 1 fi diff --git a/connect/connect-weblogic-source/weblogic-queue.sh b/connect/connect-weblogic-source/weblogic-queue.sh index c7f81f89a4..0960d6035b 100755 --- a/connect/connect-weblogic-source/weblogic-queue.sh +++ b/connect/connect-weblogic-source/weblogic-queue.sh @@ -46,7 +46,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/connect/connect-weblogic-source/weblogic-topic.sh b/connect/connect-weblogic-source/weblogic-topic.sh index b2474dfda3..d82ff01365 100755 --- a/connect/connect-weblogic-source/weblogic-topic.sh +++ b/connect/connect-weblogic-source/weblogic-topic.sh @@ -44,7 +44,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/other/custom-smt/filestream-sink.sh b/other/custom-smt/filestream-sink.sh index c432c2234a..8d2c4bc206 100755 --- a/other/custom-smt/filestream-sink.sh +++ b/other/custom-smt/filestream-sink.sh @@ -12,7 +12,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component " + logerror "❌ failed to build java component " tail -500 /tmp/result.log exit 1 fi diff --git a/other/http-proxy-schema-registry/start.sh b/other/http-proxy-schema-registry/start.sh index b7c0bc186c..1d069cfc4d 100755 --- a/other/http-proxy-schema-registry/start.sh +++ b/other/http-proxy-schema-registry/start.sh @@ -16,7 +16,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/other/monitoring-demo/start.sh b/other/monitoring-demo/start.sh index 1a7d55e5ad..46b42379a1 100755 --- a/other/monitoring-demo/start.sh +++ b/other/monitoring-demo/start.sh @@ -18,7 +18,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/other/schema-format-avro-with-key/start.sh b/other/schema-format-avro-with-key/start.sh index bbf2e33d8a..931dea4a00 100755 --- a/other/schema-format-avro-with-key/start.sh +++ b/other/schema-format-avro-with-key/start.sh @@ -11,7 +11,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/other/schema-format-avro/start.sh b/other/schema-format-avro/start.sh index 13f97c50be..cac427c5a4 100755 --- a/other/schema-format-avro/start.sh +++ b/other/schema-format-avro/start.sh @@ -11,7 +11,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/other/schema-format-json-schema-with-key/start.sh b/other/schema-format-json-schema-with-key/start.sh index 84c690c9be..92f572ed46 100755 --- a/other/schema-format-json-schema-with-key/start.sh +++ b/other/schema-format-json-schema-with-key/start.sh @@ -16,7 +16,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/other/schema-format-json-schema/start.sh b/other/schema-format-json-schema/start.sh index a40f89a420..ff7d397cae 100755 --- a/other/schema-format-json-schema/start.sh +++ b/other/schema-format-json-schema/start.sh @@ -16,7 +16,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/other/schema-format-protobuf-with-key/start.sh b/other/schema-format-protobuf-with-key/start.sh index 333f1c59ff..c04c011825 100755 --- a/other/schema-format-protobuf-with-key/start.sh +++ b/other/schema-format-protobuf-with-key/start.sh @@ -16,7 +16,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/other/schema-format-protobuf/start.sh b/other/schema-format-protobuf/start.sh index 20c7ba868e..7c7dcabca4 100755 --- a/other/schema-format-protobuf/start.sh +++ b/other/schema-format-protobuf/start.sh @@ -16,7 +16,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/other/tiered-storage-with-aws/start.sh b/other/tiered-storage-with-aws/start.sh index f8a8068ef4..f8cdc8a2cf 100755 --- a/other/tiered-storage-with-aws/start.sh +++ b/other/tiered-storage-with-aws/start.sh @@ -11,7 +11,7 @@ fi if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" + logerror "❌ either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" exit 1 else if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] @@ -32,7 +32,7 @@ else AWS_REGION=$(aws configure get region | tr '\r' '\n') if [ "$AWS_REGION" == "" ] then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" + logerror "❌ either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" exit 1 fi fi diff --git a/reproduction-models b/reproduction-models index f8c2df656d..9a4ac8c7dc 160000 --- a/reproduction-models +++ b/reproduction-models @@ -1 +1 @@ -Subproject commit f8c2df656d6b90c064917728aa5e9aa23394a7e9 +Subproject commit 9a4ac8c7dcf78c7e690cf2c47ea5b9ce6380a588 diff --git a/schema-registry/multiple-event-types-in-topic/start-avro.sh b/schema-registry/multiple-event-types-in-topic/start-avro.sh index 5d50586c64..3b66ca5695 100644 --- a/schema-registry/multiple-event-types-in-topic/start-avro.sh +++ b/schema-registry/multiple-event-types-in-topic/start-avro.sh @@ -6,7 +6,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh if ! version_gt $TAG_BASE "5.4.99"; then - logerror "ERROR: This can only be run with version greater than 5.5" + logerror "❌ This can only be run with version greater than 5.5" exit 111 fi diff --git a/scripts/cli/playground b/scripts/cli/playground index 2d14a4ca83..d06a9a1368 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -6699,7 +6699,7 @@ function get_ccloud_connect() { if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi @@ -6753,7 +6753,7 @@ function get_sr_url_and_security() { then source $root_folder/.ccloud/env.delta else - logerror "ERROR: $root_folder/.ccloud/env.delta has not been generated" + logerror "❌ $root_folder/.ccloud/env.delta has not been generated" exit 1 fi sr_url=$SCHEMA_REGISTRY_URL @@ -7254,7 +7254,7 @@ function add_connector_config_based_on_environment () { then source $root_folder/.ccloud/env.delta else - logerror "ERROR: $root_folder/.ccloud/env.delta has not been generated" + logerror "❌ $root_folder/.ccloud/env.delta has not been generated" exit 1 fi @@ -9804,7 +9804,7 @@ function create_or_get_oracle_image() { fi if [ ! -f ${ZIP_FILE} ] then - logerror "ERROR: ${ZIP_FILE} is missing. It must be downloaded manually in order to acknowledge user agreement" + logerror "❌ ${ZIP_FILE} is missing. It must be downloaded manually in order to acknowledge user agreement" exit 1 fi log "👷 Building $BASE_ORACLE_IMAGE docker image..it can take a while...(more than 15 minutes!)" @@ -9836,7 +9836,7 @@ function create_or_get_oracle_image() { docker container logs ${TEMP_CONTAINER} > /tmp/out.txt 2>&1 CUR_WAIT=$(( CUR_WAIT+10 )) if [[ "$CUR_WAIT" -gt "$MAX_WAIT" ]]; then - logerror "ERROR: The logs in ${TEMP_CONTAINER} container do not show 'DATABASE IS READY TO USE' after $MAX_WAIT seconds. Please troubleshoot with 'docker container ps' and 'docker container logs'.\n" + logerror "❌ The logs in ${TEMP_CONTAINER} container do not show 'DATABASE IS READY TO USE' after $MAX_WAIT seconds. Please troubleshoot with 'docker container ps' and 'docker container logs'.\n" exit 1 fi done @@ -9934,7 +9934,7 @@ function maybe_delete_ccloud_environment () { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi @@ -10212,7 +10212,7 @@ function bootstrap_ccloud_environment () { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi @@ -12562,7 +12562,7 @@ EOF AWS_REGION=$(aws configure get region | tr '\r' '\n') if [ "$AWS_REGION" == "" ] then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" + logerror "❌ either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" exit 1 fi fi @@ -13864,13 +13864,13 @@ playground_run_command() { if [ ! -f "$test_file" ] then - logerror "ERROR: test_file $test_file does not exist!" + logerror "❌ test_file $test_file does not exist!" exit 1 fi if [[ "$test_file" != *".sh" ]] then - logerror "ERROR: test_file $test_file is not a .sh file!" + logerror "❌ test_file $test_file is not a .sh file!" exit 1 fi @@ -16208,7 +16208,7 @@ playground_cleanup_cloud_resources_command() { function cleanup_aws () { if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" + logerror "❌ either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" exit 1 else if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] @@ -16230,7 +16230,7 @@ playground_cleanup_cloud_resources_command() { AWS_REGION=$(aws configure get region | tr '\r' '\n') if [ "$AWS_REGION" == "" ] then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" + logerror "❌ either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" exit 1 fi fi @@ -17384,7 +17384,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=\$KAFKA_CLIENT_TAG -e TAG=\$TAG_BASE -v "\${DIR}/\${component}":/usr/src/mymaven -v "\$HOME/.m2":/root/.m2 -v "\$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "\${DIR}/\${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=\$TAG -Dkafka.client.tag=\$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ \$? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi @@ -17558,7 +17558,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=\$KAFKA_CLIENT_TAG -e TAG=\$TAG_BASE -v "\${DIR}/\${component}":/usr/src/mymaven -v "\$HOME/.m2":/root/.m2 -v "\$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "\${DIR}/\${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=\$TAG -Dkafka.client.tag=\$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ \$? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi @@ -19618,7 +19618,7 @@ playground_get_jmx_metrics_command() { zookeeper|broker|schema-registry|connect|connect2|connect3) ;; *) - logerror "ERROR: container name not valid ! Should be one of zookeeper, broker, schema-registry, connect, connect2 or connect3" + logerror "❌ container name not valid ! Should be one of zookeeper, broker, schema-registry, connect, connect2 or connect3" exit 1 ;; esac @@ -19678,7 +19678,7 @@ playground_container_recreate_command() { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi fi @@ -19974,7 +19974,7 @@ playground_topic_get_number_records_command() { if [ ! -f $root_folder/.ccloud/librdkafka.delta ] then - logerror "ERROR: $root_folder/.ccloud/librdkafka.delta has not been generated" + logerror "❌ $root_folder/.ccloud/librdkafka.delta has not been generated" exit 1 fi tr -d '"' < $root_folder/.ccloud/librdkafka.delta > $root_folder/.ccloud/librdkafka_no_quotes_tmp.delta @@ -20099,12 +20099,12 @@ playground_topic_describe_command() { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi if [[ -n "$verbose" ]] @@ -20221,12 +20221,12 @@ playground_topic_consume_command() { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi fi @@ -20803,12 +20803,12 @@ playground_topic_produce_command() { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi fi @@ -21370,7 +21370,7 @@ playground_topic_produce_command() { docker run -i --rm -e TAG=$tag -v "${root_folder}/scripts/cli/src/schema-validator":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$root_folder/scripts/settings.xml:/tmp/settings.xml" -v "${root_folder}/scripts/cli/src/schema-validator/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$tag package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component schema-validator" + logerror "❌ failed to build java component schema-validator" tail -500 /tmp/result.log exit 1 fi @@ -21954,12 +21954,12 @@ playground_topic_create_command() { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi if [[ -n "$verbose" ]] @@ -22013,12 +22013,12 @@ playground_topic_delete_command() { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi if [[ -n "$verbose" ]] @@ -22086,12 +22086,12 @@ playground_topic_alter_command() { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi @@ -22493,12 +22493,12 @@ playground_connector_offsets_get_command() { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi else @@ -22620,12 +22620,12 @@ playground_connector_offsets_reset_command() { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi else @@ -22783,12 +22783,12 @@ playground_connector_offsets_alter_command() { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi else @@ -23002,12 +23002,12 @@ playground_connector_offsets_get_offsets_request_status_command() { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi fi @@ -23418,12 +23418,12 @@ playground_connector_show_lag_command() { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi else @@ -24229,7 +24229,7 @@ playground_connector_snippets_command() { then source $root_folder/.ccloud/env.delta else - logerror "ERROR: $root_folder/.ccloud/env.delta has not been generated" + logerror "❌ $root_folder/.ccloud/env.delta has not been generated" exit 1 fi echo -e " \"key.converter\": \"$converter_class\"," >> $converter_file diff --git a/scripts/cli/src/commands/cleanup-cloud-resources.sh b/scripts/cli/src/commands/cleanup-cloud-resources.sh index 406273d8c4..04342fd4d2 100644 --- a/scripts/cli/src/commands/cleanup-cloud-resources.sh +++ b/scripts/cli/src/commands/cleanup-cloud-resources.sh @@ -20,7 +20,7 @@ fi function cleanup_aws () { if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) then - logerror "ERROR: either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" + logerror "❌ either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" exit 1 else if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] @@ -41,7 +41,7 @@ function cleanup_aws () { AWS_REGION=$(aws configure get region | tr '\r' '\n') if [ "$AWS_REGION" == "" ] then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" + logerror "❌ either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" exit 1 fi fi diff --git a/scripts/cli/src/commands/connector/offsets/alter.sh b/scripts/cli/src/commands/connector/offsets/alter.sh index 2eaf5c354b..627fe1f37a 100644 --- a/scripts/cli/src/commands/connector/offsets/alter.sh +++ b/scripts/cli/src/commands/connector/offsets/alter.sh @@ -24,12 +24,12 @@ then then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi else diff --git a/scripts/cli/src/commands/connector/offsets/get-offsets-request-status.sh b/scripts/cli/src/commands/connector/offsets/get-offsets-request-status.sh index b7e906d8f9..03a3988cd4 100644 --- a/scripts/cli/src/commands/connector/offsets/get-offsets-request-status.sh +++ b/scripts/cli/src/commands/connector/offsets/get-offsets-request-status.sh @@ -30,12 +30,12 @@ then then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi fi diff --git a/scripts/cli/src/commands/connector/offsets/get.sh b/scripts/cli/src/commands/connector/offsets/get.sh index 0afe2be349..6f4e4129f4 100644 --- a/scripts/cli/src/commands/connector/offsets/get.sh +++ b/scripts/cli/src/commands/connector/offsets/get.sh @@ -24,12 +24,12 @@ then then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi else diff --git a/scripts/cli/src/commands/connector/offsets/reset.sh b/scripts/cli/src/commands/connector/offsets/reset.sh index 341eb9994a..5ae95bfb5c 100644 --- a/scripts/cli/src/commands/connector/offsets/reset.sh +++ b/scripts/cli/src/commands/connector/offsets/reset.sh @@ -23,12 +23,12 @@ then then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi else diff --git a/scripts/cli/src/commands/connector/show-lag.sh b/scripts/cli/src/commands/connector/show-lag.sh index 8dcb13d842..61ff1f09dc 100644 --- a/scripts/cli/src/commands/connector/show-lag.sh +++ b/scripts/cli/src/commands/connector/show-lag.sh @@ -26,12 +26,12 @@ then then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi else diff --git a/scripts/cli/src/commands/connector/snippets.sh b/scripts/cli/src/commands/connector/snippets.sh index 81cac87e98..9a024fdb94 100644 --- a/scripts/cli/src/commands/connector/snippets.sh +++ b/scripts/cli/src/commands/connector/snippets.sh @@ -85,7 +85,7 @@ then then source $root_folder/.ccloud/env.delta else - logerror "ERROR: $root_folder/.ccloud/env.delta has not been generated" + logerror "❌ $root_folder/.ccloud/env.delta has not been generated" exit 1 fi echo -e " \"key.converter\": \"$converter_class\"," >> $converter_file diff --git a/scripts/cli/src/commands/container/recreate.sh b/scripts/cli/src/commands/container/recreate.sh index dab8f57a3c..efd9cfbbfb 100644 --- a/scripts/cli/src/commands/container/recreate.sh +++ b/scripts/cli/src/commands/container/recreate.sh @@ -28,7 +28,7 @@ then then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi fi diff --git a/scripts/cli/src/commands/get-jmx-metrics.sh b/scripts/cli/src/commands/get-jmx-metrics.sh index 3a94573aac..dd5ff61a18 100644 --- a/scripts/cli/src/commands/get-jmx-metrics.sh +++ b/scripts/cli/src/commands/get-jmx-metrics.sh @@ -8,7 +8,7 @@ case "${container}" in zookeeper|broker|schema-registry|connect|connect2|connect3) ;; *) - logerror "ERROR: container name not valid ! Should be one of zookeeper, broker, schema-registry, connect, connect2 or connect3" + logerror "❌ container name not valid ! Should be one of zookeeper, broker, schema-registry, connect, connect2 or connect3" exit 1 ;; esac diff --git a/scripts/cli/src/commands/repro/bootstrap.sh b/scripts/cli/src/commands/repro/bootstrap.sh index 6948f0624e..1417f28701 100644 --- a/scripts/cli/src/commands/repro/bootstrap.sh +++ b/scripts/cli/src/commands/repro/bootstrap.sh @@ -719,7 +719,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=\$KAFKA_CLIENT_TAG -e TAG=\$TAG_BASE -v "\${DIR}/\${component}":/usr/src/mymaven -v "\$HOME/.m2":/root/.m2 -v "\$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "\${DIR}/\${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=\$TAG -Dkafka.client.tag=\$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ \$? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi @@ -893,7 +893,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=\$KAFKA_CLIENT_TAG -e TAG=\$TAG_BASE -v "\${DIR}/\${component}":/usr/src/mymaven -v "\$HOME/.m2":/root/.m2 -v "\$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "\${DIR}/\${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=\$TAG -Dkafka.client.tag=\$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ \$? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/scripts/cli/src/commands/run.sh b/scripts/cli/src/commands/run.sh index 4a21050094..eb6c971e52 100644 --- a/scripts/cli/src/commands/run.sh +++ b/scripts/cli/src/commands/run.sh @@ -57,13 +57,13 @@ fi if [ ! -f "$test_file" ] then - logerror "ERROR: test_file $test_file does not exist!" + logerror "❌ test_file $test_file does not exist!" exit 1 fi if [[ "$test_file" != *".sh" ]] then - logerror "ERROR: test_file $test_file is not a .sh file!" + logerror "❌ test_file $test_file is not a .sh file!" exit 1 fi diff --git a/scripts/cli/src/commands/topic/alter.sh b/scripts/cli/src/commands/topic/alter.sh index 28da6ce058..c3880b7d6f 100644 --- a/scripts/cli/src/commands/topic/alter.sh +++ b/scripts/cli/src/commands/topic/alter.sh @@ -23,12 +23,12 @@ else then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi diff --git a/scripts/cli/src/commands/topic/consume.sh b/scripts/cli/src/commands/topic/consume.sh index e6c9dbdfe1..f6602b85ef 100644 --- a/scripts/cli/src/commands/topic/consume.sh +++ b/scripts/cli/src/commands/topic/consume.sh @@ -55,12 +55,12 @@ then then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi fi diff --git a/scripts/cli/src/commands/topic/create.sh b/scripts/cli/src/commands/topic/create.sh index 7148855b2f..2297a01d06 100644 --- a/scripts/cli/src/commands/topic/create.sh +++ b/scripts/cli/src/commands/topic/create.sh @@ -21,12 +21,12 @@ then then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi if [[ -n "$verbose" ]] diff --git a/scripts/cli/src/commands/topic/delete.sh b/scripts/cli/src/commands/topic/delete.sh index 7916f41c30..bbad6e45d8 100644 --- a/scripts/cli/src/commands/topic/delete.sh +++ b/scripts/cli/src/commands/topic/delete.sh @@ -25,12 +25,12 @@ then then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi if [[ -n "$verbose" ]] diff --git a/scripts/cli/src/commands/topic/describe.sh b/scripts/cli/src/commands/topic/describe.sh index a9f0b20766..254d67546d 100644 --- a/scripts/cli/src/commands/topic/describe.sh +++ b/scripts/cli/src/commands/topic/describe.sh @@ -29,12 +29,12 @@ do then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi if [[ -n "$verbose" ]] diff --git a/scripts/cli/src/commands/topic/get-number-records.sh b/scripts/cli/src/commands/topic/get-number-records.sh index 792164ea77..bda95fc94f 100644 --- a/scripts/cli/src/commands/topic/get-number-records.sh +++ b/scripts/cli/src/commands/topic/get-number-records.sh @@ -52,7 +52,7 @@ do if [ ! -f $root_folder/.ccloud/librdkafka.delta ] then - logerror "ERROR: $root_folder/.ccloud/librdkafka.delta has not been generated" + logerror "❌ $root_folder/.ccloud/librdkafka.delta has not been generated" exit 1 fi tr -d '"' < $root_folder/.ccloud/librdkafka.delta > $root_folder/.ccloud/librdkafka_no_quotes_tmp.delta diff --git a/scripts/cli/src/commands/topic/produce.sh b/scripts/cli/src/commands/topic/produce.sh index 7550d88515..7d2ee2e17c 100644 --- a/scripts/cli/src/commands/topic/produce.sh +++ b/scripts/cli/src/commands/topic/produce.sh @@ -112,12 +112,12 @@ then then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi fi @@ -675,7 +675,7 @@ then docker run -i --rm -e TAG=$tag -v "${root_folder}/scripts/cli/src/schema-validator":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$root_folder/scripts/settings.xml:/tmp/settings.xml" -v "${root_folder}/scripts/cli/src/schema-validator/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$tag package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component schema-validator" + logerror "❌ failed to build java component schema-validator" tail -500 /tmp/result.log exit 1 fi diff --git a/scripts/cli/src/lib/cli_function.sh b/scripts/cli/src/lib/cli_function.sh index 453bcd3f97..ce2f0a6683 100644 --- a/scripts/cli/src/lib/cli_function.sh +++ b/scripts/cli/src/lib/cli_function.sh @@ -290,7 +290,7 @@ function get_ccloud_connect() { if [ ! -f $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta ] then - logerror "ERROR: $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" + logerror "❌ $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta has not been generated" exit 1 fi @@ -345,7 +345,7 @@ function get_sr_url_and_security() { then source $root_folder/.ccloud/env.delta else - logerror "ERROR: $root_folder/.ccloud/env.delta has not been generated" + logerror "❌ $root_folder/.ccloud/env.delta has not been generated" exit 1 fi sr_url=$SCHEMA_REGISTRY_URL @@ -849,7 +849,7 @@ function add_connector_config_based_on_environment () { then source $root_folder/.ccloud/env.delta else - logerror "ERROR: $root_folder/.ccloud/env.delta has not been generated" + logerror "❌ $root_folder/.ccloud/env.delta has not been generated" exit 1 fi diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 52378a22fd..6635b02002 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -1564,7 +1564,7 @@ function create_or_get_oracle_image() { fi if [ ! -f ${ZIP_FILE} ] then - logerror "ERROR: ${ZIP_FILE} is missing. It must be downloaded manually in order to acknowledge user agreement" + logerror "❌ ${ZIP_FILE} is missing. It must be downloaded manually in order to acknowledge user agreement" exit 1 fi log "👷 Building $BASE_ORACLE_IMAGE docker image..it can take a while...(more than 15 minutes!)" @@ -1596,7 +1596,7 @@ function create_or_get_oracle_image() { docker container logs ${TEMP_CONTAINER} > /tmp/out.txt 2>&1 CUR_WAIT=$(( CUR_WAIT+10 )) if [[ "$CUR_WAIT" -gt "$MAX_WAIT" ]]; then - logerror "ERROR: The logs in ${TEMP_CONTAINER} container do not show 'DATABASE IS READY TO USE' after $MAX_WAIT seconds. Please troubleshoot with 'docker container ps' and 'docker container logs'.\n" + logerror "❌ The logs in ${TEMP_CONTAINER} container do not show 'DATABASE IS READY TO USE' after $MAX_WAIT seconds. Please troubleshoot with 'docker container ps' and 'docker container logs'.\n" exit 1 fi done @@ -1694,7 +1694,7 @@ function maybe_delete_ccloud_environment () { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi @@ -1969,7 +1969,7 @@ function bootstrap_ccloud_environment () { then source $DELTA_CONFIGS_ENV else - logerror "ERROR: $DELTA_CONFIGS_ENV has not been generated" + logerror "❌ $DELTA_CONFIGS_ENV has not been generated" exit 1 fi @@ -4385,7 +4385,7 @@ EOF AWS_REGION=$(aws configure get region | tr '\r' '\n') if [ "$AWS_REGION" == "" ] then - logerror "ERROR: either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" + logerror "❌ either the file $HOME/.aws/config is not present or environment variables AWS_REGION is not set!" exit 1 fi fi diff --git a/troubleshooting/admin-client-issue-when-broker-down/start.sh b/troubleshooting/admin-client-issue-when-broker-down/start.sh index 1bab9beecc..4c9891983b 100755 --- a/troubleshooting/admin-client-issue-when-broker-down/start.sh +++ b/troubleshooting/admin-client-issue-when-broker-down/start.sh @@ -11,7 +11,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/troubleshooting/forward-compatibility-and-specific-records/start.sh b/troubleshooting/forward-compatibility-and-specific-records/start.sh index 12dce23f3b..59daf08cec 100755 --- a/troubleshooting/forward-compatibility-and-specific-records/start.sh +++ b/troubleshooting/forward-compatibility-and-specific-records/start.sh @@ -11,7 +11,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/troubleshooting/small-retention-timestamp-microseconds/start.sh b/troubleshooting/small-retention-timestamp-microseconds/start.sh index 358a35693e..e54462d32e 100755 --- a/troubleshooting/small-retention-timestamp-microseconds/start.sh +++ b/troubleshooting/small-retention-timestamp-microseconds/start.sh @@ -12,7 +12,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/troubleshooting/small-retention-unknown-producer-id/start.sh b/troubleshooting/small-retention-unknown-producer-id/start.sh index e7c6bdec34..eeb99ea2ed 100755 --- a/troubleshooting/small-retention-unknown-producer-id/start.sh +++ b/troubleshooting/small-retention-unknown-producer-id/start.sh @@ -13,7 +13,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/troubleshooting/small-retention/old-timestamp.sh b/troubleshooting/small-retention/old-timestamp.sh index c84e5003d0..138927ee4e 100755 --- a/troubleshooting/small-retention/old-timestamp.sh +++ b/troubleshooting/small-retention/old-timestamp.sh @@ -11,7 +11,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi diff --git a/troubleshooting/staled-consumer-group-behaviour/start.sh b/troubleshooting/staled-consumer-group-behaviour/start.sh index b2ed6c612c..e2ee372e88 100755 --- a/troubleshooting/staled-consumer-group-behaviour/start.sh +++ b/troubleshooting/staled-consumer-group-behaviour/start.sh @@ -12,7 +12,7 @@ do docker run -i --rm -e KAFKA_CLIENT_TAG=$KAFKA_CLIENT_TAG -e TAG=$TAG_BASE -v "${PWD}/${component}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/../../scripts/settings.xml:/tmp/settings.xml" -v "${PWD}/${component}/target:/usr/src/mymaven/target" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml -Dkafka.tag=$TAG -Dkafka.client.tag=$KAFKA_CLIENT_TAG package > /tmp/result.log 2>&1 if [ $? != 0 ] then - logerror "ERROR: failed to build java component $component" + logerror "❌ failed to build java component $component" tail -500 /tmp/result.log exit 1 fi From 7362459d4f2e155e7da6e264c669962b24ed03ab Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 5 Feb 2025 16:23:52 +0100 Subject: [PATCH 205/659] =?UTF-8?q?=F0=9F=91=BE=20Add=20missing=20ActiveMQ?= =?UTF-8?q?=20fully=20managed=20connector=20example=20#6247?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ccloud/fm-active-mq-source/README.md | 17 ++++ ccloud/fm-active-mq-source/docker-compose.yml | 30 +++++++ .../fully-managed-active-mq-source.sh | 86 +++++++++++++++++++ ccloud/fm-active-mq-source/ngrok.yml | 5 ++ ccloud/fm-active-mq-source/stop.sh | 8 ++ docs/content-template.md | 1 + 6 files changed, 147 insertions(+) create mode 100644 ccloud/fm-active-mq-source/README.md create mode 100644 ccloud/fm-active-mq-source/docker-compose.yml create mode 100755 ccloud/fm-active-mq-source/fully-managed-active-mq-source.sh create mode 100644 ccloud/fm-active-mq-source/ngrok.yml create mode 100755 ccloud/fm-active-mq-source/stop.sh diff --git a/ccloud/fm-active-mq-source/README.md b/ccloud/fm-active-mq-source/README.md new file mode 100644 index 0000000000..268e4b8415 --- /dev/null +++ b/ccloud/fm-active-mq-source/README.md @@ -0,0 +1,17 @@ +# Fully Managed ActiveMQ Source connector + + + +## Objective + +Quickly test [Fully Managed ActiveMQ Source](https://docs.confluent.io/cloud/current/connectors/cc-activemq-source.html) connector. + +Using ActiveMQ Docker [image](https://hub.docker.com/r/rmohr/activemq/) + +## How to run + +Simply run: + +``` +$ just use command and search for active-mq-source.sh in this folder +``` diff --git a/ccloud/fm-active-mq-source/docker-compose.yml b/ccloud/fm-active-mq-source/docker-compose.yml new file mode 100644 index 0000000000..2a8bb34f82 --- /dev/null +++ b/ccloud/fm-active-mq-source/docker-compose.yml @@ -0,0 +1,30 @@ +--- +services: + activemq: + image: rmohr/activemq:5.15.9 + hostname: activemq + container_name: activemq + ports: + - '61616:61616' + - '8161:8161' + + # https://ngrok.com/docs/using-ngrok-with/docker/ + ngrok: + image: ngrok/ngrok:latest + hostname: ngrok + container_name: ngrok + ports: + - 4040:4040 + restart: unless-stopped + links: + - activemq + command: + - "start" + - "--all" + - "--log=stdout" + - "--config" + - "/etc/ngrok.yml" + volumes: + - ../../ccloud/fm-active-mq-source/ngrok.yml:/etc/ngrok.yml + environment: + NGROK_AUTHTOKEN: $NGROK_AUTH_TOKEN \ No newline at end of file diff --git a/ccloud/fm-active-mq-source/fully-managed-active-mq-source.sh b/ccloud/fm-active-mq-source/fully-managed-active-mq-source.sh new file mode 100755 index 0000000000..44cddf2cb2 --- /dev/null +++ b/ccloud/fm-active-mq-source/fully-managed-active-mq-source.sh @@ -0,0 +1,86 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +NGROK_AUTH_TOKEN=${NGROK_AUTH_TOKEN:-$1} + +display_ngrok_warning + +bootstrap_ccloud_environment + + + +set +e +playground topic delete --topic MyKafkaTopicName +set -e + +docker compose build +docker compose down -v --remove-orphans +docker compose up -d --quiet-pull + +sleep 5 + +log "Waiting for ngrok to start" +while true +do + container_id=$(docker ps -q -f name=ngrok) + if [ -n "$container_id" ] + then + status=$(docker inspect --format '{{.State.Status}}' $container_id) + if [ "$status" = "running" ] + then + log "Getting ngrok hostname and port" + NGROK_URL=$(curl --silent http://127.0.0.1:4040/api/tunnels | jq -r '.tunnels[0].public_url') + NGROK_HOSTNAME=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 1) + NGROK_PORT=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 2) + + if ! [[ $NGROK_PORT =~ ^[0-9]+$ ]] + then + log "NGROK_PORT is not a valid number, keep retrying..." + continue + else + break + fi + fi + fi + log "Waiting for container ngrok to start..." + sleep 5 +done + +connector_name="ActiveMQSource_$USER" +set +e +playground connector delete --connector $connector_name > /dev/null 2>&1 +set -e + +log "Creating fully managed connector" +playground connector create-or-update --connector $connector_name << EOF +{ + "connector.class": "ActiveMQSource", + "name": "$connector_name", + "kafka.auth.mode": "KAFKA_API_KEY", + "kafka.api.key": "$CLOUD_KEY", + "kafka.api.secret": "$CLOUD_SECRET", + "output.data.format": "AVRO", + "kafka.topic": "MyKafkaTopicName", + "activemq.url": "tcp://$NGROK_HOSTNAME:$NGROK_PORT", + "activemq.username": "admin", + "activemq.password": "admin", + "jms.destination.name": "DEV.QUEUE.1", + "jms.destination.type": "queue", + "jms.destination.name": "DEV.QUEUE.1", + "jms.destination.type": "queue", + "tasks.max" : "1" +} +EOF +wait_for_ccloud_connector_up $connector_name 180 + + +log "Sending messages to DEV.QUEUE.1 JMS queue:" +curl -XPOST -u admin:admin -d "body=message" http://localhost:8161/api/message/DEV.QUEUE.1?type=queue + +sleep 5 + +log "Verify we have received the data in MyKafkaTopicName topic" +playground topic consume --topic MyKafkaTopicName --min-expected-messages 1 --timeout 60 diff --git a/ccloud/fm-active-mq-source/ngrok.yml b/ccloud/fm-active-mq-source/ngrok.yml new file mode 100644 index 0000000000..340b5cae3f --- /dev/null +++ b/ccloud/fm-active-mq-source/ngrok.yml @@ -0,0 +1,5 @@ +version: 2 +tunnels: + activemq: + addr: activemq:61616 + proto: tcp \ No newline at end of file diff --git a/ccloud/fm-active-mq-source/stop.sh b/ccloud/fm-active-mq-source/stop.sh new file mode 100755 index 0000000000..bab6807da5 --- /dev/null +++ b/ccloud/fm-active-mq-source/stop.sh @@ -0,0 +1,8 @@ +#!/bin/bash + + + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +stop_all "$DIR" \ No newline at end of file diff --git a/docs/content-template.md b/docs/content-template.md index b137e4c8f6..b2058f16de 100644 --- a/docs/content-template.md +++ b/docs/content-template.md @@ -180,6 +180,7 @@ ### 🤖 Fully-Managed Connectors + - [ActiveMQ Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-active-mq-source) :ccloud/fm-active-mq-source: - [Amazon CloudWatch Logs Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-aws-cloudwatch-logs-source) :ccloud/fm-aws-cloudwatch-logs-source: - [Amazon CloudWatch Metrics Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-aws-cloudwatch-metrics-sink) :ccloud/fm-aws-cloudwatch-metrics-sink: - [Amazon DynamoDB CDC Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-aws-dynamodb-cdc-source) :ccloud/fm-aws-dynamodb-cdc-source: From 9466a1f39c4804dfccf7dbac7980d6659d3064a3 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 5 Feb 2025 16:26:56 +0100 Subject: [PATCH 206/659] cosmetic --- scripts/cli/src/lib/cli_function.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/cli/src/lib/cli_function.sh b/scripts/cli/src/lib/cli_function.sh index ce2f0a6683..87b46dd7bf 100644 --- a/scripts/cli/src/lib/cli_function.sh +++ b/scripts/cli/src/lib/cli_function.sh @@ -1581,7 +1581,9 @@ function check_for_ec2_instance_running() { # loop through the list for instance in $(echo $current_list | tr "|" "\n") do - log "🤑👛 you have an ec2 instance $instance running" + log "💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸" + log "🤑 you have an ec2 instance $instance running !" + log "💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸" done fi } From 641bebcd6db4252ab25ba5d44869894a0e4c3549 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 5 Feb 2025 16:29:36 +0100 Subject: [PATCH 207/659] fm-active-mq-source --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6f32a4af8d..56009377b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -140,7 +140,7 @@ jobs: # requiring ngrok "🚀2️⃣ ccloud/fm-influxdb2-sink ccloud/fm-influxdb2-source ccloud/fm-jdbc-oracle19-source ccloud/fm-jdbc-oracle19-sink ccloud/fm-cdc-oracle19-source ccloud/fm-rabbitmq-source ccloud/fm-zendesk-source ccloud/fm-splunk-sink ccloud/fm-rabbitmq-sink ccloud/fm-jdbc-mysql-sink ccloud/fm-sftp-source ccloud/fm-http-sink ccloud/fm-http-v2-sink ccloud/fm-http-source ccloud/fm-http-v2-source", - "🚀3️⃣ ccloud/fm-cdc-oracle11-source ccloud/fm-solace-sink ccloud/fm-opensearch-sink ccloud/fm-sftp-sink ccloud/fm-redis-sink" + "🚀3️⃣ ccloud/fm-cdc-oracle11-source ccloud/fm-solace-sink ccloud/fm-opensearch-sink ccloud/fm-sftp-sink ccloud/fm-redis-sink ccloud/fm-active-mq-source" ] steps: From 14a9db096c28d812b175a6e476e0452fff2e5264 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 5 Feb 2025 16:34:16 +0100 Subject: [PATCH 208/659] wip --- scripts/cli/playground | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index d06a9a1368..e9cb326fca 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8021,7 +8021,9 @@ function check_for_ec2_instance_running() { # loop through the list for instance in $(echo $current_list | tr "|" "\n") do - log "🤑👛 you have an ec2 instance $instance running" + log "💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸" + log "🤑 you have an ec2 instance $instance running !" + log "💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸" done fi } From 84ca72d4e5ded5952bf9d83909ade6fec8fe37b7 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 5 Feb 2025 16:50:33 +0100 Subject: [PATCH 209/659] wip --- scripts/cli/playground | 18 +++++++++--------- scripts/cli/src/lib/utils_function.sh | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index e9cb326fca..7f235b71af 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -12263,15 +12263,15 @@ function generate_connector_versions () { fi } -readonly CONNECTOR_TYPE_FULLY_MANAGED="🌤️🤖fully managed" -readonly CONNECTOR_TYPE_CUSTOM="🌤️🛃custom" -readonly CONNECTOR_TYPE_SELF_MANAGED="⛈️👷self managed" -readonly CONNECTOR_TYPE_ONPREM="🌎onprem" - -readonly EC2_INSTANCE_STATE_STOPPED="🛑stopped" -readonly EC2_INSTANCE_STATE_RUNNING="✅running" -readonly EC2_INSTANCE_STATE_STOPPING="⌛stopping" -readonly EC2_INSTANCE_STATE_PENDING="⌛pending" +CONNECTOR_TYPE_FULLY_MANAGED="🌤️🤖fully managed" +CONNECTOR_TYPE_CUSTOM="🌤️🛃custom" +CONNECTOR_TYPE_SELF_MANAGED="⛈️👷self managed" +CONNECTOR_TYPE_ONPREM="🌎onprem" + +EC2_INSTANCE_STATE_STOPPED="🛑stopped" +EC2_INSTANCE_STATE_RUNNING="✅running" +EC2_INSTANCE_STATE_STOPPING="⌛stopping" +EC2_INSTANCE_STATE_PENDING="⌛pending" function get_connector_type () { get_connector_paths diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 6635b02002..a111ecf458 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -4087,15 +4087,15 @@ function generate_connector_versions () { fi } -readonly CONNECTOR_TYPE_FULLY_MANAGED="🌤️🤖fully managed" -readonly CONNECTOR_TYPE_CUSTOM="🌤️🛃custom" -readonly CONNECTOR_TYPE_SELF_MANAGED="⛈️👷self managed" -readonly CONNECTOR_TYPE_ONPREM="🌎onprem" - -readonly EC2_INSTANCE_STATE_STOPPED="🛑stopped" -readonly EC2_INSTANCE_STATE_RUNNING="✅running" -readonly EC2_INSTANCE_STATE_STOPPING="⌛stopping" -readonly EC2_INSTANCE_STATE_PENDING="⌛pending" +CONNECTOR_TYPE_FULLY_MANAGED="🌤️🤖fully managed" +CONNECTOR_TYPE_CUSTOM="🌤️🛃custom" +CONNECTOR_TYPE_SELF_MANAGED="⛈️👷self managed" +CONNECTOR_TYPE_ONPREM="🌎onprem" + +EC2_INSTANCE_STATE_STOPPED="🛑stopped" +EC2_INSTANCE_STATE_RUNNING="✅running" +EC2_INSTANCE_STATE_STOPPING="⌛stopping" +EC2_INSTANCE_STATE_PENDING="⌛pending" function get_connector_type () { get_connector_paths From 122efa1c38dca46a796408862986873aefc8ccb8 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Feb 2025 09:46:31 +0100 Subject: [PATCH 210/659] =?UTF-8?q?=F0=9F=A7=A0=20playground=20connector?= =?UTF-8?q?=20restart=20is=20now=20available=20for=20fully=20managed=20con?= =?UTF-8?q?nectors=20#6253?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 46 ++++++++++-------- scripts/cli/src/commands/connector/restart.sh | 48 ++++++++++--------- 2 files changed, 51 insertions(+), 43 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 7f235b71af..44eb8df63e 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -23205,19 +23205,12 @@ playground_connector_restart_command() { fi fi - if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] + if [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] then log "connector restart command is not supported with $connector_type connector" exit 0 fi - tag=$(docker ps --format '{{.Image}}' | egrep 'confluentinc/cp-.*-connect-base:' | awk -F':' '{print $2}') - if [ $? != 0 ] || [ "$tag" == "" ] - then - logerror "Could not find current CP version from docker ps" - exit 1 - fi - items=($connector) length=${#items[@]} if ((length > 1)) @@ -23227,23 +23220,34 @@ playground_connector_restart_command() { for connector in "${items[@]}" do log "🔄 Restarting $connector_type connector $connector" - - get_connect_url_and_security - log "🔄 Restarting connector $connector" - if ! version_gt $tag "6.9.9" + if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] #|| [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] then - handle_onprem_connect_rest_api "curl $security -s -X GET \"$connect_url/connectors/$connector/tasks" + get_ccloud_connect + handle_ccloud_connect_rest_api "curl -s --request POST \"https://api.confluent.cloud/connect/v1/environments/$environment/clusters/$cluster/connectors/$connector/restart\" --header \"authorization: Basic $authorization\"" + else + tag=$(docker ps --format '{{.Image}}' | egrep 'confluentinc/cp-.*-connect-base:' | awk -F':' '{print $2}') + if [ $? != 0 ] || [ "$tag" == "" ] + then + logerror "Could not find current CP version from docker ps" + exit 1 + fi + get_connect_url_and_security + if ! version_gt $tag "6.9.9" + then + handle_onprem_connect_rest_api "curl $security -s -X GET \"$connect_url/connectors/$connector/tasks" - task_ids=$(echo "$curl_output" | jq -r '.[].id.task') + task_ids=$(echo "$curl_output" | jq -r '.[].id.task') - for task_id in $task_ids - do - log "🤹‍♂️ Restart task $task_id" - handle_onprem_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" \"$connect_url/connectors/$connector/tasks/$task_id/restart\"" - done - else - handle_onprem_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" \"$connect_url/connectors/$connector/restart?includeTasks=true&onlyFailed=false\"" + for task_id in $task_ids + do + log "🤹‍♂️ Restart task $task_id" + handle_onprem_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" \"$connect_url/connectors/$connector/tasks/$task_id/restart\"" + done + else + handle_onprem_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" \"$connect_url/connectors/$connector/restart?includeTasks=true&onlyFailed=false\"" + fi fi + log "🔄 $connector_type connector $connector has been restarted successfully" done sleep 3 diff --git a/scripts/cli/src/commands/connector/restart.sh b/scripts/cli/src/commands/connector/restart.sh index cdeca05c26..ad3d2ac560 100644 --- a/scripts/cli/src/commands/connector/restart.sh +++ b/scripts/cli/src/commands/connector/restart.sh @@ -13,19 +13,12 @@ then fi fi -if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] +if [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] then log "connector restart command is not supported with $connector_type connector" exit 0 fi -tag=$(docker ps --format '{{.Image}}' | egrep 'confluentinc/cp-.*-connect-base:' | awk -F':' '{print $2}') -if [ $? != 0 ] || [ "$tag" == "" ] -then - logerror "Could not find current CP version from docker ps" - exit 1 -fi - items=($connector) length=${#items[@]} if ((length > 1)) @@ -35,23 +28,34 @@ fi for connector in "${items[@]}" do log "🔄 Restarting $connector_type connector $connector" - - get_connect_url_and_security - log "🔄 Restarting connector $connector" - if ! version_gt $tag "6.9.9" + if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] #|| [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] then - handle_onprem_connect_rest_api "curl $security -s -X GET \"$connect_url/connectors/$connector/tasks" - - task_ids=$(echo "$curl_output" | jq -r '.[].id.task') - - for task_id in $task_ids - do - log "🤹‍♂️ Restart task $task_id" - handle_onprem_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" \"$connect_url/connectors/$connector/tasks/$task_id/restart\"" - done + get_ccloud_connect + handle_ccloud_connect_rest_api "curl -s --request POST \"https://api.confluent.cloud/connect/v1/environments/$environment/clusters/$cluster/connectors/$connector/restart\" --header \"authorization: Basic $authorization\"" else - handle_onprem_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" \"$connect_url/connectors/$connector/restart?includeTasks=true&onlyFailed=false\"" + tag=$(docker ps --format '{{.Image}}' | egrep 'confluentinc/cp-.*-connect-base:' | awk -F':' '{print $2}') + if [ $? != 0 ] || [ "$tag" == "" ] + then + logerror "Could not find current CP version from docker ps" + exit 1 + fi + get_connect_url_and_security + if ! version_gt $tag "6.9.9" + then + handle_onprem_connect_rest_api "curl $security -s -X GET \"$connect_url/connectors/$connector/tasks" + + task_ids=$(echo "$curl_output" | jq -r '.[].id.task') + + for task_id in $task_ids + do + log "🤹‍♂️ Restart task $task_id" + handle_onprem_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" \"$connect_url/connectors/$connector/tasks/$task_id/restart\"" + done + else + handle_onprem_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" \"$connect_url/connectors/$connector/restart?includeTasks=true&onlyFailed=false\"" + fi fi + log "🔄 $connector_type connector $connector has been restarted successfully" done sleep 3 From 1ababa3a2ea58a91dfe7a0c1dc1d0f24ddec3bff Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Feb 2025 10:52:25 +0100 Subject: [PATCH 211/659] =?UTF-8?q?=F0=9F=A7=A0=20remove=20SLF4J=20traces?= =?UTF-8?q?=20from=20topic=20produce=20#6254?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 2 ++ scripts/cli/src/commands/topic/produce.sh | 2 ++ 2 files changed, 4 insertions(+) diff --git a/scripts/cli/playground b/scripts/cli/playground index 44eb8df63e..0b36fad62d 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -21836,6 +21836,8 @@ playground_topic_produce_command() { fi fi else + # 🧠 remove SLF4J traces from topic produce #6254 + playground container exec --command "rm -f /usr/share/java/schema-registry/slf4j-reload4j-1.7.36.jar > /dev/null 2>&1" --root if [ -f $key_schema_file ] then docker cp $key_schema_file $container:/tmp/key_schema_file > /dev/null 2>&1 diff --git a/scripts/cli/src/commands/topic/produce.sh b/scripts/cli/src/commands/topic/produce.sh index 7d2ee2e17c..c957173c8a 100644 --- a/scripts/cli/src/commands/topic/produce.sh +++ b/scripts/cli/src/commands/topic/produce.sh @@ -1134,6 +1134,8 @@ do fi fi else + # 🧠 remove SLF4J traces from topic produce #6254 + playground container exec --command "rm -f /usr/share/java/schema-registry/slf4j-reload4j-1.7.36.jar > /dev/null 2>&1" --root if [ -f $key_schema_file ] then docker cp $key_schema_file $container:/tmp/key_schema_file > /dev/null 2>&1 From 7b2b1115387e609d079181fb729748feaf433e42 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Feb 2025 13:31:32 +0100 Subject: [PATCH 212/659] use GITHUB_RUN_NUMBER --- .../fully-managed-gcp-pubsub-source.sh | 28 +++++++++---------- .../connect-gcp-google-pubsub-sink/README.md | 10 +++---- .../gcp-google-pubsub-sink.sh | 22 +++++++-------- .../README.md | 20 ++++++------- .../gcp-google-pubsub-source.sh | 28 +++++++++---------- connect/connect-gcp-pubsub-source/README.md | 20 ++++++------- .../gcp-pubsub-source-nginx-proxy.sh | 28 +++++++++---------- .../gcp-pubsub-source.sh | 28 +++++++++---------- 8 files changed, 92 insertions(+), 92 deletions(-) diff --git a/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh b/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh index 7a63383094..9cdb89c2de 100755 --- a/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh +++ b/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh @@ -46,31 +46,31 @@ docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cl # cleanup if required set +e log "Delete topic and subscription, if required" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1 -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1 +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER set -e -log "Create a Pub/Sub topic called topic-1" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create topic-1 +log "Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create topic-1-$GITHUB_RUN_NUMBER -log "Create a Pub/Sub subscription called subscription-1" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic topic-1 subscription-1 --ack-deadline 60 +log "Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER --ack-deadline 60 function cleanup_cloud_resources { set +e log "Delete GCP PubSub topic and subscription" check_if_continue - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1 - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1 + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER docker rm -f gcloud-config } trap cleanup_cloud_resources EXIT -log "Publish three messages to topic-1" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1 --message "Peter" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1 --message "Megan" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1 --message "Erin" +log "Publish three messages to topic-1-$GITHUB_RUN_NUMBER" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Peter" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Megan" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Erin" connector_name="PubSubSource_$USER" set +e @@ -88,8 +88,8 @@ playground connector create-or-update --connector $connector_name << EOF "kafka.topic" : "pubsub-topic", "gcp.pubsub.credentials.json" : "$GCP_KEYFILE_CONTENT", "gcp.pubsub.project.id" : "$GCP_PROJECT", - "gcp.pubsub.topic.id" : "topic-1", - "gcp.pubsub.subscription.id" : "subscription-1", + "gcp.pubsub.topic.id" : "topic-1-$GITHUB_RUN_NUMBER", + "gcp.pubsub.subscription.id" : "subscription-1-$GITHUB_RUN_NUMBER", "tasks.max" : "1" } EOF diff --git a/connect/connect-gcp-google-pubsub-sink/README.md b/connect/connect-gcp-google-pubsub-sink/README.md index fa5e9bc0c2..347be70873 100644 --- a/connect/connect-gcp-google-pubsub-sink/README.md +++ b/connect/connect-gcp-google-pubsub-sink/README.md @@ -48,16 +48,16 @@ Doing gsutil authentication $ gcloud auth activate-service-account --key-file ${GCP_KEYFILE} ``` -Create a Pub/Sub topic called topic-1 +Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER ```bash -$ gcloud pubsub topics create topic-1 +$ gcloud pubsub topics create topic-1-$GITHUB_RUN_NUMBER ``` -Create a Pub/Sub subscription called subscription-1 +Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER ```bash -$ gcloud pubsub subscriptions create --topic topic-1 subscription-1 +$ gcloud pubsub subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER ``` @@ -71,7 +71,7 @@ $ curl -X PUT \ "tasks.max" : "1", "topics" : "pubsub-topic", "cps.project" : "$GCP_PROJECT", - "cps.topic" : "topic-1", + "cps.topic" : "topic-1-$GITHUB_RUN_NUMBER", "gcp.credentials.file.path" : "/tmp/keyfile.json", "key.converter": "org.apache.kafka.connect.storage.StringConverter", "value.converter": "org.apache.kafka.connect.converters.ByteArrayConverter", diff --git a/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh b/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh index 127dcb1e03..7bf13fd390 100755 --- a/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh +++ b/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh @@ -56,22 +56,22 @@ docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cl # cleanup if required set +e log "Delete topic and subscription, if required" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1 -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1 +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER set -e -log "Create a Pub/Sub topic called topic-1" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create topic-1 +log "Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create topic-1-$GITHUB_RUN_NUMBER -log "Create a Pub/Sub subscription called subscription-1" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic topic-1 subscription-1 +log "Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER function cleanup_cloud_resources { set +e log "Delete GCP PubSub topic and subscription" check_if_continue - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1 - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1 + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER docker rm -f gcloud-config } @@ -108,7 +108,7 @@ playground connector create-or-update --connector pubsub-sink << EOF "tasks.max" : "1", "topics" : "pubsub-topic", "cps.project" : "$GCP_PROJECT", - "cps.topic" : "topic-1", + "cps.topic" : "topic-1-$GITHUB_RUN_NUMBER", "gcp.credentials.file.path" : "/tmp/keyfile.json", "key.converter": "org.apache.kafka.connect.storage.StringConverter", "value.converter": "org.apache.kafka.connect.converters.ByteArrayConverter", @@ -119,7 +119,7 @@ EOF sleep 120 -log "Get messages from topic-1" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions pull subscription-1 > /tmp/result.log 2>&1 +log "Get messages from topic-1-$GITHUB_RUN_NUMBER" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions pull subscription-1-$GITHUB_RUN_NUMBER > /tmp/result.log 2>&1 cat /tmp/result.log grep "MESSAGE_ID" /tmp/result.log \ No newline at end of file diff --git a/connect/connect-gcp-google-pubsub-source/README.md b/connect/connect-gcp-google-pubsub-source/README.md index 9f063c1063..73a4e41af8 100644 --- a/connect/connect-gcp-google-pubsub-source/README.md +++ b/connect/connect-gcp-google-pubsub-source/README.md @@ -48,24 +48,24 @@ Doing gsutil authentication $ gcloud auth activate-service-account --key-file ${GCP_KEYFILE} ``` -Create a Pub/Sub topic called topic-1 +Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER ```bash -$ gcloud pubsub topics create topic-1 +$ gcloud pubsub topics create topic-1-$GITHUB_RUN_NUMBER ``` -Create a Pub/Sub subscription called subscription-1 +Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER ```bash -$ gcloud pubsub subscriptions create --topic topic-1 subscription-1 +$ gcloud pubsub subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER ``` -Publish three messages to topic-1 +Publish three messages to topic-1-$GITHUB_RUN_NUMBER ```bash -$ gcloud pubsub topics publish topic-1 --message "Peter" -gcloud pubsub topics publish topic-1 --message "Megan" -gcloud pubsub topics publish topic-1 --message "Erin" +$ gcloud pubsub topics publish topic-1-$GITHUB_RUN_NUMBER --message "Peter" +gcloud pubsub topics publish topic-1-$GITHUB_RUN_NUMBER --message "Megan" +gcloud pubsub topics publish topic-1-$GITHUB_RUN_NUMBER --message "Erin" ``` Creating reating Google Cloud Pub/Sub Group Kafka Source connector @@ -78,8 +78,8 @@ $ curl -X PUT \ "tasks.max" : "1", "kafka.topic" : "pubsub-topic", "cps.project" : "$GCP_PROJECT", - "cps.topic" : "topic-1", - "cps.subscription" : "subscription-1", + "cps.topic" : "topic-1-$GITHUB_RUN_NUMBER", + "cps.subscription" : "subscription-1-$GITHUB_RUN_NUMBER", "gcp.credentials.file.path" : "/tmp/keyfile.json", "errors.tolerance": "all", "errors.log.enable": "true", diff --git a/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh b/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh index e8894117d4..144b9a10da 100755 --- a/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh +++ b/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh @@ -56,31 +56,31 @@ docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cl # cleanup if required set +e log "Delete topic and subscription, if required" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1 -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1 +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER set -e -log "Create a Pub/Sub topic called topic-1" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create topic-1 +log "Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create topic-1-$GITHUB_RUN_NUMBER -log "Create a Pub/Sub subscription called subscription-1" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic topic-1 subscription-1 --ack-deadline 60 +log "Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER --ack-deadline 60 function cleanup_cloud_resources { set +e log "Delete GCP PubSub topic and subscription" check_if_continue - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1 - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1 + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER docker rm -f gcloud-config } trap cleanup_cloud_resources EXIT -log "Publish three messages to topic-1" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1 --message "Peter" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1 --message "Megan" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1 --message "Erin" +log "Publish three messages to topic-1-$GITHUB_RUN_NUMBER" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Peter" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Megan" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Erin" sleep 10 @@ -91,8 +91,8 @@ playground connector create-or-update --connector pubsub-source << EOF "tasks.max" : "1", "kafka.topic" : "pubsub-topic", "cps.project" : "$GCP_PROJECT", - "cps.topic" : "topic-1", - "cps.subscription" : "subscription-1", + "cps.topic" : "topic-1-$GITHUB_RUN_NUMBER", + "cps.subscription" : "subscription-1-$GITHUB_RUN_NUMBER", "gcp.credentials.file.path" : "/tmp/keyfile.json", "errors.tolerance": "all", "errors.log.enable": "true", diff --git a/connect/connect-gcp-pubsub-source/README.md b/connect/connect-gcp-pubsub-source/README.md index bb87424c52..4c60d91b54 100644 --- a/connect/connect-gcp-pubsub-source/README.md +++ b/connect/connect-gcp-pubsub-source/README.md @@ -48,24 +48,24 @@ Doing gsutil authentication $ gcloud auth activate-service-account --key-file ${GCP_KEYFILE} ``` -Create a Pub/Sub topic called topic-1 +Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER ```bash -$ gcloud pubsub topics create topic-1 +$ gcloud pubsub topics create topic-1-$GITHUB_RUN_NUMBER ``` -Create a Pub/Sub subscription called subscription-1 +Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER ```bash -$ gcloud pubsub subscriptions create --topic topic-1 subscription-1 +$ gcloud pubsub subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER ``` -Publish three messages to topic-1 +Publish three messages to topic-1-$GITHUB_RUN_NUMBER ```bash -$ gcloud pubsub topics publish topic-1 --message "Peter" -gcloud pubsub topics publish topic-1 --message "Megan" -gcloud pubsub topics publish topic-1 --message "Erin" +$ gcloud pubsub topics publish topic-1-$GITHUB_RUN_NUMBER --message "Peter" +gcloud pubsub topics publish topic-1-$GITHUB_RUN_NUMBER --message "Megan" +gcloud pubsub topics publish topic-1-$GITHUB_RUN_NUMBER --message "Erin" ``` Creating GCP PubSub Source connector @@ -78,8 +78,8 @@ $ curl -X PUT \ "tasks.max" : "1", "kafka.topic" : "pubsub-topic", "gcp.pubsub.project.id" : "$GCP_PROJECT", - "gcp.pubsub.topic.id" : "topic-1", - "gcp.pubsub.subscription.id" : "subscription-1", + "gcp.pubsub.topic.id" : "topic-1-$GITHUB_RUN_NUMBER", + "gcp.pubsub.subscription.id" : "subscription-1-$GITHUB_RUN_NUMBER", "gcp.pubsub.credentials.path" : "/tmp/keyfile.json", "confluent.topic.bootstrap.servers": "broker:9092", "confluent.topic.replication.factor": "1" diff --git a/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh b/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh index 752fbb054b..af2d078c9a 100755 --- a/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh +++ b/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh @@ -46,31 +46,31 @@ docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cl # cleanup if required set +e log "Delete topic and subscription, if required" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1 -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1 +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER set -e -log "Create a Pub/Sub topic called topic-1" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create topic-1 +log "Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create topic-1-$GITHUB_RUN_NUMBER -log "Create a Pub/Sub subscription called subscription-1" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic topic-1 subscription-1 --ack-deadline 60 +log "Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER --ack-deadline 60 function cleanup_cloud_resources { set +e log "Delete GCP PubSub topic and subscription" check_if_continue - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1 - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1 + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER docker rm -f gcloud-config } trap cleanup_cloud_resources EXIT -log "Publish three messages to topic-1" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1 --message "Peter" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1 --message "Megan" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1 --message "Erin" +log "Publish three messages to topic-1-$GITHUB_RUN_NUMBER" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Peter" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Megan" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Erin" sleep 10 @@ -81,8 +81,8 @@ playground connector create-or-update --connector pubsub-source << EOF "tasks.max" : "1", "kafka.topic" : "pubsub-topic", "gcp.pubsub.project.id" : "$GCP_PROJECT", - "gcp.pubsub.topic.id" : "topic-1", - "gcp.pubsub.subscription.id" : "subscription-1", + "gcp.pubsub.topic.id" : "topic-1-$GITHUB_RUN_NUMBER", + "gcp.pubsub.subscription.id" : "subscription-1-$GITHUB_RUN_NUMBER", "gcp.pubsub.credentials.path" : "/tmp/keyfile.json", "gcp.pubsub.proxy.url": "nginx_http2_proxy:8888", "confluent.topic.bootstrap.servers": "broker:9092", diff --git a/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh b/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh index b0d7638bbc..3f92611ff7 100755 --- a/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh +++ b/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh @@ -40,31 +40,31 @@ docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cl # cleanup if required set +e log "Delete topic and subscription, if required" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1 -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1 +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER set -e -log "Create a Pub/Sub topic called topic-1" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create topic-1 +log "Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create topic-1-$GITHUB_RUN_NUMBER -log "Create a Pub/Sub subscription called subscription-1" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic topic-1 subscription-1 --ack-deadline 60 +log "Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER --ack-deadline 60 function cleanup_cloud_resources { set +e log "Delete GCP PubSub topic and subscription" check_if_continue - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1 - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1 + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER docker rm -f gcloud-config } trap cleanup_cloud_resources EXIT -log "Publish three messages to topic-1" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1 --message "Peter" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1 --message "Megan" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1 --message "Erin" +log "Publish three messages to topic-1-$GITHUB_RUN_NUMBER" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Peter" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Megan" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Erin" sleep 10 @@ -75,8 +75,8 @@ playground connector create-or-update --connector pubsub-source << EOF "tasks.max" : "1", "kafka.topic" : "pubsub-topic", "gcp.pubsub.project.id" : "$GCP_PROJECT", - "gcp.pubsub.topic.id" : "topic-1", - "gcp.pubsub.subscription.id" : "subscription-1", + "gcp.pubsub.topic.id" : "topic-1-$GITHUB_RUN_NUMBER", + "gcp.pubsub.subscription.id" : "subscription-1-$GITHUB_RUN_NUMBER", "gcp.pubsub.credentials.path" : "/tmp/keyfile.json", "confluent.topic.bootstrap.servers": "broker:9092", "confluent.topic.replication.factor": "1", From 98995a1ab0f6e368c6e2258f66ccffd154dba2cb Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Feb 2025 13:31:44 +0100 Subject: [PATCH 213/659] fix wait_container_ready --- scripts/cli/playground | 8 ++++++-- scripts/cli/src/lib/utils_function.sh | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 0b36fad62d..50fafb88d8 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -9286,16 +9286,20 @@ function stop_all() { function wait_container_ready() { CONNECT_CONTAINER=${1:-"connect"} - CONTROL_CENTER_CONTAINER=${1:-"control-center"} + CONTROL_CENTER_CONTAINER={$1:-"control-center"} MAX_WAIT=300 if [ ! -z $WAIT_FOR_CONTROL_CENTER ] then log "⌛ Waiting up to $MAX_WAIT seconds for ${CONTROL_CENTER_CONTAINER} to start" playground --output-level WARN container logs --container $CONTROL_CENTER_CONTAINER --wait-for-log "Started NetworkTrafficServerConnector" --max-wait $MAX_WAIT - else + elif [[ $CONNECT_CONTAINER == connect* ]] + then log "⌛ Waiting up to $MAX_WAIT seconds for ${CONNECT_CONTAINER} to start" playground container wait-for-connect-rest-api-ready --max-wait $MAX_WAIT + else + log "⌛ Waiting up to $MAX_WAIT seconds for ${CONNECT_CONTAINER} to start" + playground --output-level WARN container logs --container $CONNECT_CONTAINER --wait-for-log "Finished starting connectors and tasks" --max-wait $MAX_WAIT fi # Verify Docker containers started if [[ $(docker container ps) =~ "Exit 137" ]] diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index a111ecf458..0515d1486a 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -1041,16 +1041,20 @@ function stop_all() { function wait_container_ready() { CONNECT_CONTAINER=${1:-"connect"} - CONTROL_CENTER_CONTAINER=${1:-"control-center"} + CONTROL_CENTER_CONTAINER={$1:-"control-center"} MAX_WAIT=300 if [ ! -z $WAIT_FOR_CONTROL_CENTER ] then log "⌛ Waiting up to $MAX_WAIT seconds for ${CONTROL_CENTER_CONTAINER} to start" playground --output-level WARN container logs --container $CONTROL_CENTER_CONTAINER --wait-for-log "Started NetworkTrafficServerConnector" --max-wait $MAX_WAIT - else + elif [[ $CONNECT_CONTAINER == connect* ]] + then log "⌛ Waiting up to $MAX_WAIT seconds for ${CONNECT_CONTAINER} to start" playground container wait-for-connect-rest-api-ready --max-wait $MAX_WAIT + else + log "⌛ Waiting up to $MAX_WAIT seconds for ${CONNECT_CONTAINER} to start" + playground --output-level WARN container logs --container $CONNECT_CONTAINER --wait-for-log "Finished starting connectors and tasks" --max-wait $MAX_WAIT fi # Verify Docker containers started if [[ $(docker container ps) =~ "Exit 137" ]] From d0f05e8b42958bf9d4ab9181b00c812b2d7badbb Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Feb 2025 13:35:24 +0100 Subject: [PATCH 214/659] pgfm --- .../fully-managed-azure-service-bus-source.sh | 2 +- ccloud/fm-azure-service-bus-source/stop.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ccloud/fm-azure-service-bus-source/fully-managed-azure-service-bus-source.sh b/ccloud/fm-azure-service-bus-source/fully-managed-azure-service-bus-source.sh index 5246f9fb13..d9c4b9872e 100755 --- a/ccloud/fm-azure-service-bus-source/fully-managed-azure-service-bus-source.sh +++ b/ccloud/fm-azure-service-bus-source/fully-managed-azure-service-bus-source.sh @@ -36,7 +36,7 @@ else az login fi -AZURE_NAME=pg${USER}sb${GITHUB_RUN_NUMBER}${TAG} +AZURE_NAME=pgfm${USER}sb${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} AZURE_RESOURCE_GROUP=$AZURE_NAME AZURE_SERVICE_BUS_NAMESPACE=$AZURE_NAME diff --git a/ccloud/fm-azure-service-bus-source/stop.sh b/ccloud/fm-azure-service-bus-source/stop.sh index ad30f46d90..a4a296b9c2 100755 --- a/ccloud/fm-azure-service-bus-source/stop.sh +++ b/ccloud/fm-azure-service-bus-source/stop.sh @@ -9,7 +9,7 @@ docker compose down -v --remove-orphans maybe_delete_ccloud_environment -AZURE_NAME=pg${USER}sb${GITHUB_RUN_NUMBER}${TAG} +AZURE_NAME=pgfm${USER}sb${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} AZURE_RESOURCE_GROUP=$AZURE_NAME From e94d72dd6184137809e7d55a1c2a51fd98a4cf1a Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Feb 2025 13:36:42 +0100 Subject: [PATCH 215/659] pgfm --- .../fm-aws-cloudwatch-logs-source/fully-managed-cloudwatch.sh | 4 ++-- .../fully-managed-dynamodb-cdc-source.sh | 2 +- ccloud/fm-aws-dynamodb-sink/fully-managed-dynamodb-sink.sh | 2 +- ccloud/fm-aws-kinesis-source/fully-managed-kinesis-source.sh | 2 +- ccloud/fm-aws-lambda-sink/fully-managed-lambda-sink.sh | 4 ++-- ccloud/fm-aws-redshift-sink/fully-managed-redshift-sink.sh | 2 +- ccloud/fm-aws-sqs-source/fully-managed-sqs-source.sh | 2 +- .../fully-managed-azure-blob-storage-sink.sh | 2 +- .../fully-managed-azure-blob-storage-source.sh | 2 +- .../fully-managed-azure-cognitive-search-sink.sh | 4 ++-- .../fully-managed-azure-cosmosdb-sink.sh | 2 +- .../fully-managed-azure-cosmosdb-source.sh | 2 +- .../fully-managed-azure-data-lake-storage-gen2-sink.sh | 4 ++-- .../fully-managed-azure-event-hubs.sh | 2 +- .../fully-managed-azure-functions-sink.sh | 2 +- .../fully-managed-azure-log-analytics-sink.sh | 2 +- .../fully-managed-azure-synapse-analytics-sink.sh | 2 +- .../fully-managed-gcp-bigquery-sink-legacy.sh | 2 +- .../fully-managed-gcp-bigquery-sink-v2.sh | 2 +- 19 files changed, 23 insertions(+), 23 deletions(-) diff --git a/ccloud/fm-aws-cloudwatch-logs-source/fully-managed-cloudwatch.sh b/ccloud/fm-aws-cloudwatch-logs-source/fully-managed-cloudwatch.sh index 82f3bafa92..dcc5ee03e6 100755 --- a/ccloud/fm-aws-cloudwatch-logs-source/fully-managed-cloudwatch.sh +++ b/ccloud/fm-aws-cloudwatch-logs-source/fully-managed-cloudwatch.sh @@ -8,9 +8,9 @@ handle_aws_credentials bootstrap_ccloud_environment -LOG_GROUP=pg${USER}lg${TAG} +LOG_GROUP=pgfm${USER}lg${TAG} LOG_GROUP=${LOG_GROUP//[-.]/} -LOG_STREAM=pg${USER}ls${TAG} +LOG_STREAM=pgfm${USER}ls${TAG} LOG_STREAM=${LOG_STREAM//[-.]/} TOPIC="$LOG_GROUP.$LOG_STREAM" diff --git a/ccloud/fm-aws-dynamodb-cdc-source/fully-managed-dynamodb-cdc-source.sh b/ccloud/fm-aws-dynamodb-cdc-source/fully-managed-dynamodb-cdc-source.sh index 067745c3d3..5bceb58c65 100755 --- a/ccloud/fm-aws-dynamodb-cdc-source/fully-managed-dynamodb-cdc-source.sh +++ b/ccloud/fm-aws-dynamodb-cdc-source/fully-managed-dynamodb-cdc-source.sh @@ -12,7 +12,7 @@ fi handle_aws_credentials -DYNAMODB_TABLE="pg${USER}dynamocdc${TAG}" +DYNAMODB_TABLE="pgfm${USER}dynamocdc${TAG}" set +e log "Delete table, this might fail" diff --git a/ccloud/fm-aws-dynamodb-sink/fully-managed-dynamodb-sink.sh b/ccloud/fm-aws-dynamodb-sink/fully-managed-dynamodb-sink.sh index c6f3f4bd13..135ade03af 100755 --- a/ccloud/fm-aws-dynamodb-sink/fully-managed-dynamodb-sink.sh +++ b/ccloud/fm-aws-dynamodb-sink/fully-managed-dynamodb-sink.sh @@ -12,7 +12,7 @@ fi handle_aws_credentials -DYNAMODB_TABLE="pg${USER}dynamo${TAG}" +DYNAMODB_TABLE="pgfm${USER}dynamo${TAG}" set +e log "Delete table, this might fail" diff --git a/ccloud/fm-aws-kinesis-source/fully-managed-kinesis-source.sh b/ccloud/fm-aws-kinesis-source/fully-managed-kinesis-source.sh index 2a92bde322..f2c3866322 100755 --- a/ccloud/fm-aws-kinesis-source/fully-managed-kinesis-source.sh +++ b/ccloud/fm-aws-kinesis-source/fully-managed-kinesis-source.sh @@ -14,7 +14,7 @@ sleep 3 playground topic create --topic kinesis_topic --nb-partitions 1 set -e -KINESIS_STREAM_NAME=pg${USER}${TAG} +KINESIS_STREAM_NAME=pgfm${USER}${TAG} KINESIS_STREAM_NAME=${KINESIS_STREAM_NAME//[-.]/} set +e diff --git a/ccloud/fm-aws-lambda-sink/fully-managed-lambda-sink.sh b/ccloud/fm-aws-lambda-sink/fully-managed-lambda-sink.sh index cdfaa9608b..ac96214d36 100755 --- a/ccloud/fm-aws-lambda-sink/fully-managed-lambda-sink.sh +++ b/ccloud/fm-aws-lambda-sink/fully-managed-lambda-sink.sh @@ -6,10 +6,10 @@ source ${DIR}/../../scripts/utils.sh handle_aws_credentials -LAMBDA_ROLE_NAME=pg${USER}lambdabrole${TAG} +LAMBDA_ROLE_NAME=pgfm${USER}lambdabrole${TAG} LAMBDA_ROLE_NAME=${LAMBDA_ROLE_NAME//[-._]/} -LAMBDA_FUNCTION_NAME=pg${USER}lambdafn${TAG} +LAMBDA_FUNCTION_NAME=pgfm${USER}lambdafn${TAG} LAMBDA_FUNCTION_NAME=${LAMBDA_FUNCTION_NAME//[-._]/} set +e diff --git a/ccloud/fm-aws-redshift-sink/fully-managed-redshift-sink.sh b/ccloud/fm-aws-redshift-sink/fully-managed-redshift-sink.sh index 7ed942fc02..fcdf25c10b 100755 --- a/ccloud/fm-aws-redshift-sink/fully-managed-redshift-sink.sh +++ b/ccloud/fm-aws-redshift-sink/fully-managed-redshift-sink.sh @@ -14,7 +14,7 @@ sleep 3 playground topic create --topic orders --nb-partitions 1 set -e -CLUSTER_NAME=pg${USER}redshift${TAG} +CLUSTER_NAME=pgfm${USER}redshift${TAG} CLUSTER_NAME=${CLUSTER_NAME//[-._]/} PASSWORD=$(date +%s | cksum | base64 | head -c 32 ; echo) diff --git a/ccloud/fm-aws-sqs-source/fully-managed-sqs-source.sh b/ccloud/fm-aws-sqs-source/fully-managed-sqs-source.sh index e41624395b..5a2759be7a 100755 --- a/ccloud/fm-aws-sqs-source/fully-managed-sqs-source.sh +++ b/ccloud/fm-aws-sqs-source/fully-managed-sqs-source.sh @@ -14,7 +14,7 @@ sleep 3 playground topic create --topic test-sqs-source --nb-partitions 1 set -e -QUEUE_NAME=pg${USER}sqs${TAG} +QUEUE_NAME=pgfm${USER}sqs${TAG} QUEUE_NAME=${QUEUE_NAME//[-._]/} QUEUE_URL_RAW=$(aws sqs create-queue --queue-name $QUEUE_NAME | jq .QueueUrl) diff --git a/ccloud/fm-azure-blob-storage-sink/fully-managed-azure-blob-storage-sink.sh b/ccloud/fm-azure-blob-storage-sink/fully-managed-azure-blob-storage-sink.sh index edece52749..abc8edbdc8 100755 --- a/ccloud/fm-azure-blob-storage-sink/fully-managed-azure-blob-storage-sink.sh +++ b/ccloud/fm-azure-blob-storage-sink/fully-managed-azure-blob-storage-sink.sh @@ -19,7 +19,7 @@ fi # when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription maybe_set_azure_subscription -AZURE_NAME=pg${USER}bk${GITHUB_RUN_NUMBER}${TAG} +AZURE_NAME=pgfm${USER}bk${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} AZURE_RESOURCE_GROUP=$AZURE_NAME AZURE_ACCOUNT_NAME=$AZURE_NAME diff --git a/ccloud/fm-azure-blob-storage-source/fully-managed-azure-blob-storage-source.sh b/ccloud/fm-azure-blob-storage-source/fully-managed-azure-blob-storage-source.sh index 705ce2508d..c0cc0ecacd 100755 --- a/ccloud/fm-azure-blob-storage-source/fully-managed-azure-blob-storage-source.sh +++ b/ccloud/fm-azure-blob-storage-source/fully-managed-azure-blob-storage-source.sh @@ -19,7 +19,7 @@ fi # when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription maybe_set_azure_subscription -AZURE_NAME=pg${USER}bs${GITHUB_RUN_NUMBER}${TAG} +AZURE_NAME=pgfm${USER}bs${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} AZURE_RESOURCE_GROUP=$AZURE_NAME AZURE_ACCOUNT_NAME=$AZURE_NAME diff --git a/ccloud/fm-azure-cognitive-search-sink/fully-managed-azure-cognitive-search-sink.sh b/ccloud/fm-azure-cognitive-search-sink/fully-managed-azure-cognitive-search-sink.sh index de0cac1de7..1255ba0f8c 100755 --- a/ccloud/fm-azure-cognitive-search-sink/fully-managed-azure-cognitive-search-sink.sh +++ b/ccloud/fm-azure-cognitive-search-sink/fully-managed-azure-cognitive-search-sink.sh @@ -19,12 +19,12 @@ fi # when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription maybe_set_azure_subscription -AZURE_NAME=pg${USER}s${GITHUB_RUN_NUMBER}${TAG} +AZURE_NAME=pgfm${USER}s${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} AZURE_RESOURCE_GROUP=$AZURE_NAME AZURE_SEARCH_SERVICE_NAME=$AZURE_NAME AZURE_REGION=westeurope -AZURE_AD_APP=pg${USER} +AZURE_AD_APP=pgfm${USER} set +e az group delete --name $AZURE_RESOURCE_GROUP --yes diff --git a/ccloud/fm-azure-cosmosdb-sink/fully-managed-azure-cosmosdb-sink.sh b/ccloud/fm-azure-cosmosdb-sink/fully-managed-azure-cosmosdb-sink.sh index fa22cfe33b..01b8924ecf 100755 --- a/ccloud/fm-azure-cosmosdb-sink/fully-managed-azure-cosmosdb-sink.sh +++ b/ccloud/fm-azure-cosmosdb-sink/fully-managed-azure-cosmosdb-sink.sh @@ -30,7 +30,7 @@ set -e # https://github.com/microsoft/kafka-connect-cosmosdb/blob/dev/doc/CosmosDB_Setup.md -AZURE_NAME=pg${USER}cs${GITHUB_RUN_NUMBER}${TAG} +AZURE_NAME=pgfm${USER}cs${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} AZURE_REGION=westeurope AZURE_RESOURCE_GROUP=$AZURE_NAME diff --git a/ccloud/fm-azure-cosmosdb-source/fully-managed-azure-cosmosdb-source.sh b/ccloud/fm-azure-cosmosdb-source/fully-managed-azure-cosmosdb-source.sh index 36bf9f0fb7..4fc987dc11 100755 --- a/ccloud/fm-azure-cosmosdb-source/fully-managed-azure-cosmosdb-source.sh +++ b/ccloud/fm-azure-cosmosdb-source/fully-managed-azure-cosmosdb-source.sh @@ -29,7 +29,7 @@ playground topic create --topic apparels --nb-partitions 1 set -e # https://github.com/microsoft/kafka-connect-cosmosdb/blob/dev/doc/CosmosDB_Setup.md -AZURE_NAME=pg${USER}ck${GITHUB_RUN_NUMBER}${TAG} +AZURE_NAME=pgfm${USER}ck${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} AZURE_REGION=westeurope AZURE_RESOURCE_GROUP=$AZURE_NAME diff --git a/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh b/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh index db9875a34a..77442d36a1 100755 --- a/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh +++ b/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh @@ -19,11 +19,11 @@ fi # when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription maybe_set_azure_subscription -AZURE_NAME=pg${USER}dl${GITHUB_RUN_NUMBER}${TAG} +AZURE_NAME=pgfm${USER}dl${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} AZURE_RESOURCE_GROUP=$AZURE_NAME AZURE_DATALAKE_ACCOUNT_NAME=$AZURE_NAME -AZURE_AD_APP_NAME=pg${USER} +AZURE_AD_APP_NAME=pgfm${USER} AZURE_REGION=westeurope set +e diff --git a/ccloud/fm-azure-event-hubs-source/fully-managed-azure-event-hubs.sh b/ccloud/fm-azure-event-hubs-source/fully-managed-azure-event-hubs.sh index 3286983c3e..959f2d7ce4 100755 --- a/ccloud/fm-azure-event-hubs-source/fully-managed-azure-event-hubs.sh +++ b/ccloud/fm-azure-event-hubs-source/fully-managed-azure-event-hubs.sh @@ -37,7 +37,7 @@ else az login fi -AZURE_NAME=pg${USER}feh${GITHUB_RUN_NUMBER}${TAG} +AZURE_NAME=pgfm${USER}feh${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} AZURE_RESOURCE_GROUP=$AZURE_NAME AZURE_EVENT_HUBS_NAMESPACE=ns$AZURE_NAME diff --git a/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh b/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh index 24c29275f9..f984c732d9 100755 --- a/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh +++ b/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh @@ -19,7 +19,7 @@ fi # when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription maybe_set_azure_subscription -AZURE_NAME=pg${USER}fm${GITHUB_RUN_NUMBER}${TAG} +AZURE_NAME=pgfm${USER}fm${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} AZURE_RESOURCE_GROUP=$AZURE_NAME AZURE_STORAGE_NAME=$AZURE_NAME diff --git a/ccloud/fm-azure-log-analytics-sink/fully-managed-azure-log-analytics-sink.sh b/ccloud/fm-azure-log-analytics-sink/fully-managed-azure-log-analytics-sink.sh index a80252c524..8473a3ad90 100755 --- a/ccloud/fm-azure-log-analytics-sink/fully-managed-azure-log-analytics-sink.sh +++ b/ccloud/fm-azure-log-analytics-sink/fully-managed-azure-log-analytics-sink.sh @@ -19,7 +19,7 @@ fi # when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription maybe_set_azure_subscription -AZURE_NAME=pg${USER}la${GITHUB_RUN_NUMBER}${TAG} +AZURE_NAME=pgfm${USER}la${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} AZURE_RESOURCE_GROUP=$AZURE_NAME diff --git a/ccloud/fm-azure-synapse-analytics-sink/fully-managed-azure-synapse-analytics-sink.sh b/ccloud/fm-azure-synapse-analytics-sink/fully-managed-azure-synapse-analytics-sink.sh index f69e1e8219..73ccb3195f 100755 --- a/ccloud/fm-azure-synapse-analytics-sink/fully-managed-azure-synapse-analytics-sink.sh +++ b/ccloud/fm-azure-synapse-analytics-sink/fully-managed-azure-synapse-analytics-sink.sh @@ -19,7 +19,7 @@ fi # when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription maybe_set_azure_subscription -AZURE_NAME=pg${USER}wh${GITHUB_RUN_NUMBER}${TAG} +AZURE_NAME=pgfm${USER}wh${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} AZURE_RESOURCE_GROUP=$AZURE_NAME AZURE_SQL_NAME=$AZURE_NAME diff --git a/ccloud/fm-gcp-bigquery-legacy-sink/fully-managed-gcp-bigquery-sink-legacy.sh b/ccloud/fm-gcp-bigquery-legacy-sink/fully-managed-gcp-bigquery-sink-legacy.sh index fef87dd0f1..f8d01b98ea 100755 --- a/ccloud/fm-gcp-bigquery-legacy-sink/fully-managed-gcp-bigquery-sink-legacy.sh +++ b/ccloud/fm-gcp-bigquery-legacy-sink/fully-managed-gcp-bigquery-sink-legacy.sh @@ -31,7 +31,7 @@ bootstrap_ccloud_environment -DATASET=pg${USER}ds${GITHUB_RUN_NUMBER}${TAG} +DATASET=pgfm${USER}ds${GITHUB_RUN_NUMBER}${TAG} DATASET=${DATASET//[-._]/} log "Doing gsutil authentication" diff --git a/ccloud/fm-gcp-bigquery-v2-sink/fully-managed-gcp-bigquery-sink-v2.sh b/ccloud/fm-gcp-bigquery-v2-sink/fully-managed-gcp-bigquery-sink-v2.sh index 2a588eed61..f58c915626 100755 --- a/ccloud/fm-gcp-bigquery-v2-sink/fully-managed-gcp-bigquery-sink-v2.sh +++ b/ccloud/fm-gcp-bigquery-v2-sink/fully-managed-gcp-bigquery-sink-v2.sh @@ -31,7 +31,7 @@ bootstrap_ccloud_environment -DATASET=pg${USER}ds${GITHUB_RUN_NUMBER}${TAG} +DATASET=pgfm${USER}ds${GITHUB_RUN_NUMBER}${TAG} DATASET=${DATASET//[-._]/} log "Doing gsutil authentication" From aa452fccd7a7e0dd811c24cf33ac825843be1069 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Feb 2025 15:52:37 +0100 Subject: [PATCH 216/659] variable --- .../fully-managed-gcp-pubsub-source.sh | 31 ++++++++++--------- .../connect-gcp-google-pubsub-sink/README.md | 10 +++--- .../gcp-google-pubsub-sink.sh | 24 +++++++------- .../README.md | 20 ++++++------ .../gcp-google-pubsub-source.sh | 30 +++++++++--------- connect/connect-gcp-pubsub-source/README.md | 20 ++++++------ .../gcp-pubsub-source-nginx-proxy.sh | 30 +++++++++--------- .../gcp-pubsub-source.sh | 30 +++++++++--------- reproduction-models | 2 +- 9 files changed, 104 insertions(+), 93 deletions(-) diff --git a/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh b/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh index 9cdb89c2de..9eb06443e8 100755 --- a/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh +++ b/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh @@ -29,6 +29,9 @@ cd - bootstrap_ccloud_environment +GCP_PUB_SUB_TOPIC="topic-1-$GITHUB_RUN_NUMBER" +GCP_PUB_SUB_SUBSCRIPTION="subscription-1-$GITHUB_RUN_NUMBER" + set +e playground topic delete --topic pubsub-topic sleep 3 @@ -46,31 +49,31 @@ docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cl # cleanup if required set +e log "Delete topic and subscription, if required" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION set -e -log "Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create topic-1-$GITHUB_RUN_NUMBER +log "Create a Pub/Sub topic called $GCP_PUB_SUB_TOPIC" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create $GCP_PUB_SUB_TOPIC -log "Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER --ack-deadline 60 +log "Create a Pub/Sub subscription called $GCP_PUB_SUB_SUBSCRIPTION" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic $GCP_PUB_SUB_TOPIC $GCP_PUB_SUB_SUBSCRIPTION --ack-deadline 60 function cleanup_cloud_resources { set +e log "Delete GCP PubSub topic and subscription" check_if_continue - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION docker rm -f gcloud-config } trap cleanup_cloud_resources EXIT -log "Publish three messages to topic-1-$GITHUB_RUN_NUMBER" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Peter" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Megan" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Erin" +log "Publish three messages to $GCP_PUB_SUB_TOPIC" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish $GCP_PUB_SUB_TOPIC --message "Peter" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish $GCP_PUB_SUB_TOPIC --message "Megan" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish $GCP_PUB_SUB_TOPIC --message "Erin" connector_name="PubSubSource_$USER" set +e @@ -88,8 +91,8 @@ playground connector create-or-update --connector $connector_name << EOF "kafka.topic" : "pubsub-topic", "gcp.pubsub.credentials.json" : "$GCP_KEYFILE_CONTENT", "gcp.pubsub.project.id" : "$GCP_PROJECT", - "gcp.pubsub.topic.id" : "topic-1-$GITHUB_RUN_NUMBER", - "gcp.pubsub.subscription.id" : "subscription-1-$GITHUB_RUN_NUMBER", + "gcp.pubsub.topic.id" : "$GCP_PUB_SUB_TOPIC", + "gcp.pubsub.subscription.id" : "$GCP_PUB_SUB_SUBSCRIPTION", "tasks.max" : "1" } EOF diff --git a/connect/connect-gcp-google-pubsub-sink/README.md b/connect/connect-gcp-google-pubsub-sink/README.md index 347be70873..9f557fbf52 100644 --- a/connect/connect-gcp-google-pubsub-sink/README.md +++ b/connect/connect-gcp-google-pubsub-sink/README.md @@ -48,16 +48,16 @@ Doing gsutil authentication $ gcloud auth activate-service-account --key-file ${GCP_KEYFILE} ``` -Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER +Create a Pub/Sub topic called $GCP_PUB_SUB_TOPIC ```bash -$ gcloud pubsub topics create topic-1-$GITHUB_RUN_NUMBER +$ gcloud pubsub topics create $GCP_PUB_SUB_TOPIC ``` -Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER +Create a Pub/Sub subscription called $GCP_PUB_SUB_SUBSCRIPTION ```bash -$ gcloud pubsub subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER +$ gcloud pubsub subscriptions create --topic $GCP_PUB_SUB_TOPIC $GCP_PUB_SUB_SUBSCRIPTION ``` @@ -71,7 +71,7 @@ $ curl -X PUT \ "tasks.max" : "1", "topics" : "pubsub-topic", "cps.project" : "$GCP_PROJECT", - "cps.topic" : "topic-1-$GITHUB_RUN_NUMBER", + "cps.topic" : "$GCP_PUB_SUB_TOPIC", "gcp.credentials.file.path" : "/tmp/keyfile.json", "key.converter": "org.apache.kafka.connect.storage.StringConverter", "value.converter": "org.apache.kafka.connect.converters.ByteArrayConverter", diff --git a/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh b/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh index 7bf13fd390..907de176f5 100755 --- a/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh +++ b/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh @@ -52,26 +52,28 @@ docker rm -f gcloud-config set -e docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cloud-sdk:latest gcloud auth activate-service-account --project ${GCP_PROJECT} --key-file /tmp/keyfile.json +GCP_PUB_SUB_TOPIC="topic-1-$GITHUB_RUN_NUMBER" +GCP_PUB_SUB_SUBSCRIPTION="subscription-1-$GITHUB_RUN_NUMBER" # cleanup if required set +e log "Delete topic and subscription, if required" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION set -e -log "Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create topic-1-$GITHUB_RUN_NUMBER +log "Create a Pub/Sub topic called $GCP_PUB_SUB_TOPIC" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create $GCP_PUB_SUB_TOPIC -log "Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER +log "Create a Pub/Sub subscription called $GCP_PUB_SUB_SUBSCRIPTION" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic $GCP_PUB_SUB_TOPIC $GCP_PUB_SUB_SUBSCRIPTION function cleanup_cloud_resources { set +e log "Delete GCP PubSub topic and subscription" check_if_continue - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION docker rm -f gcloud-config } @@ -108,7 +110,7 @@ playground connector create-or-update --connector pubsub-sink << EOF "tasks.max" : "1", "topics" : "pubsub-topic", "cps.project" : "$GCP_PROJECT", - "cps.topic" : "topic-1-$GITHUB_RUN_NUMBER", + "cps.topic" : "$GCP_PUB_SUB_TOPIC", "gcp.credentials.file.path" : "/tmp/keyfile.json", "key.converter": "org.apache.kafka.connect.storage.StringConverter", "value.converter": "org.apache.kafka.connect.converters.ByteArrayConverter", @@ -119,7 +121,7 @@ EOF sleep 120 -log "Get messages from topic-1-$GITHUB_RUN_NUMBER" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions pull subscription-1-$GITHUB_RUN_NUMBER > /tmp/result.log 2>&1 +log "Get messages from $GCP_PUB_SUB_TOPIC" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions pull $GCP_PUB_SUB_SUBSCRIPTION > /tmp/result.log 2>&1 cat /tmp/result.log grep "MESSAGE_ID" /tmp/result.log \ No newline at end of file diff --git a/connect/connect-gcp-google-pubsub-source/README.md b/connect/connect-gcp-google-pubsub-source/README.md index 73a4e41af8..ba39695e64 100644 --- a/connect/connect-gcp-google-pubsub-source/README.md +++ b/connect/connect-gcp-google-pubsub-source/README.md @@ -48,24 +48,24 @@ Doing gsutil authentication $ gcloud auth activate-service-account --key-file ${GCP_KEYFILE} ``` -Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER +Create a Pub/Sub topic called $GCP_PUB_SUB_TOPIC ```bash -$ gcloud pubsub topics create topic-1-$GITHUB_RUN_NUMBER +$ gcloud pubsub topics create $GCP_PUB_SUB_TOPIC ``` -Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER +Create a Pub/Sub subscription called $GCP_PUB_SUB_SUBSCRIPTION ```bash -$ gcloud pubsub subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER +$ gcloud pubsub subscriptions create --topic $GCP_PUB_SUB_TOPIC $GCP_PUB_SUB_SUBSCRIPTION ``` -Publish three messages to topic-1-$GITHUB_RUN_NUMBER +Publish three messages to $GCP_PUB_SUB_TOPIC ```bash -$ gcloud pubsub topics publish topic-1-$GITHUB_RUN_NUMBER --message "Peter" -gcloud pubsub topics publish topic-1-$GITHUB_RUN_NUMBER --message "Megan" -gcloud pubsub topics publish topic-1-$GITHUB_RUN_NUMBER --message "Erin" +$ gcloud pubsub topics publish $GCP_PUB_SUB_TOPIC --message "Peter" +gcloud pubsub topics publish $GCP_PUB_SUB_TOPIC --message "Megan" +gcloud pubsub topics publish $GCP_PUB_SUB_TOPIC --message "Erin" ``` Creating reating Google Cloud Pub/Sub Group Kafka Source connector @@ -78,8 +78,8 @@ $ curl -X PUT \ "tasks.max" : "1", "kafka.topic" : "pubsub-topic", "cps.project" : "$GCP_PROJECT", - "cps.topic" : "topic-1-$GITHUB_RUN_NUMBER", - "cps.subscription" : "subscription-1-$GITHUB_RUN_NUMBER", + "cps.topic" : "$GCP_PUB_SUB_TOPIC", + "cps.subscription" : "$GCP_PUB_SUB_SUBSCRIPTION", "gcp.credentials.file.path" : "/tmp/keyfile.json", "errors.tolerance": "all", "errors.log.enable": "true", diff --git a/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh b/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh index 144b9a10da..8eaac072e5 100755 --- a/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh +++ b/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh @@ -52,35 +52,37 @@ docker rm -f gcloud-config set -e docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cloud-sdk:latest gcloud auth activate-service-account --project ${GCP_PROJECT} --key-file /tmp/keyfile.json +GCP_PUB_SUB_TOPIC="topic-1-$GITHUB_RUN_NUMBER" +GCP_PUB_SUB_SUBSCRIPTION="subscription-1-$GITHUB_RUN_NUMBER" # cleanup if required set +e log "Delete topic and subscription, if required" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION set -e -log "Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create topic-1-$GITHUB_RUN_NUMBER +log "Create a Pub/Sub topic called $GCP_PUB_SUB_TOPIC" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create $GCP_PUB_SUB_TOPIC -log "Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER --ack-deadline 60 +log "Create a Pub/Sub subscription called $GCP_PUB_SUB_SUBSCRIPTION" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic $GCP_PUB_SUB_TOPIC $GCP_PUB_SUB_SUBSCRIPTION --ack-deadline 60 function cleanup_cloud_resources { set +e log "Delete GCP PubSub topic and subscription" check_if_continue - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION docker rm -f gcloud-config } trap cleanup_cloud_resources EXIT -log "Publish three messages to topic-1-$GITHUB_RUN_NUMBER" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Peter" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Megan" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Erin" +log "Publish three messages to $GCP_PUB_SUB_TOPIC" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish $GCP_PUB_SUB_TOPIC --message "Peter" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish $GCP_PUB_SUB_TOPIC --message "Megan" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish $GCP_PUB_SUB_TOPIC --message "Erin" sleep 10 @@ -91,8 +93,8 @@ playground connector create-or-update --connector pubsub-source << EOF "tasks.max" : "1", "kafka.topic" : "pubsub-topic", "cps.project" : "$GCP_PROJECT", - "cps.topic" : "topic-1-$GITHUB_RUN_NUMBER", - "cps.subscription" : "subscription-1-$GITHUB_RUN_NUMBER", + "cps.topic" : "$GCP_PUB_SUB_TOPIC", + "cps.subscription" : "$GCP_PUB_SUB_SUBSCRIPTION", "gcp.credentials.file.path" : "/tmp/keyfile.json", "errors.tolerance": "all", "errors.log.enable": "true", diff --git a/connect/connect-gcp-pubsub-source/README.md b/connect/connect-gcp-pubsub-source/README.md index 4c60d91b54..2e22236bda 100644 --- a/connect/connect-gcp-pubsub-source/README.md +++ b/connect/connect-gcp-pubsub-source/README.md @@ -48,24 +48,24 @@ Doing gsutil authentication $ gcloud auth activate-service-account --key-file ${GCP_KEYFILE} ``` -Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER +Create a Pub/Sub topic called $GCP_PUB_SUB_TOPIC ```bash -$ gcloud pubsub topics create topic-1-$GITHUB_RUN_NUMBER +$ gcloud pubsub topics create $GCP_PUB_SUB_TOPIC ``` -Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER +Create a Pub/Sub subscription called $GCP_PUB_SUB_SUBSCRIPTION ```bash -$ gcloud pubsub subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER +$ gcloud pubsub subscriptions create --topic $GCP_PUB_SUB_TOPIC $GCP_PUB_SUB_SUBSCRIPTION ``` -Publish three messages to topic-1-$GITHUB_RUN_NUMBER +Publish three messages to $GCP_PUB_SUB_TOPIC ```bash -$ gcloud pubsub topics publish topic-1-$GITHUB_RUN_NUMBER --message "Peter" -gcloud pubsub topics publish topic-1-$GITHUB_RUN_NUMBER --message "Megan" -gcloud pubsub topics publish topic-1-$GITHUB_RUN_NUMBER --message "Erin" +$ gcloud pubsub topics publish $GCP_PUB_SUB_TOPIC --message "Peter" +gcloud pubsub topics publish $GCP_PUB_SUB_TOPIC --message "Megan" +gcloud pubsub topics publish $GCP_PUB_SUB_TOPIC --message "Erin" ``` Creating GCP PubSub Source connector @@ -78,8 +78,8 @@ $ curl -X PUT \ "tasks.max" : "1", "kafka.topic" : "pubsub-topic", "gcp.pubsub.project.id" : "$GCP_PROJECT", - "gcp.pubsub.topic.id" : "topic-1-$GITHUB_RUN_NUMBER", - "gcp.pubsub.subscription.id" : "subscription-1-$GITHUB_RUN_NUMBER", + "gcp.pubsub.topic.id" : "$GCP_PUB_SUB_TOPIC", + "gcp.pubsub.subscription.id" : "$GCP_PUB_SUB_SUBSCRIPTION", "gcp.pubsub.credentials.path" : "/tmp/keyfile.json", "confluent.topic.bootstrap.servers": "broker:9092", "confluent.topic.replication.factor": "1" diff --git a/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh b/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh index af2d078c9a..22564d292e 100755 --- a/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh +++ b/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh @@ -42,35 +42,37 @@ docker rm -f gcloud-config set -e docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cloud-sdk:latest gcloud auth activate-service-account --project ${GCP_PROJECT} --key-file /tmp/keyfile.json +GCP_PUB_SUB_TOPIC="topic-1-$GITHUB_RUN_NUMBER" +GCP_PUB_SUB_SUBSCRIPTION="subscription-1-$GITHUB_RUN_NUMBER" # cleanup if required set +e log "Delete topic and subscription, if required" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION set -e -log "Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create topic-1-$GITHUB_RUN_NUMBER +log "Create a Pub/Sub topic called $GCP_PUB_SUB_TOPIC" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create $GCP_PUB_SUB_TOPIC -log "Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER --ack-deadline 60 +log "Create a Pub/Sub subscription called $GCP_PUB_SUB_SUBSCRIPTION" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic $GCP_PUB_SUB_TOPIC $GCP_PUB_SUB_SUBSCRIPTION --ack-deadline 60 function cleanup_cloud_resources { set +e log "Delete GCP PubSub topic and subscription" check_if_continue - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION docker rm -f gcloud-config } trap cleanup_cloud_resources EXIT -log "Publish three messages to topic-1-$GITHUB_RUN_NUMBER" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Peter" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Megan" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Erin" +log "Publish three messages to $GCP_PUB_SUB_TOPIC" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish $GCP_PUB_SUB_TOPIC --message "Peter" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish $GCP_PUB_SUB_TOPIC --message "Megan" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish $GCP_PUB_SUB_TOPIC --message "Erin" sleep 10 @@ -81,8 +83,8 @@ playground connector create-or-update --connector pubsub-source << EOF "tasks.max" : "1", "kafka.topic" : "pubsub-topic", "gcp.pubsub.project.id" : "$GCP_PROJECT", - "gcp.pubsub.topic.id" : "topic-1-$GITHUB_RUN_NUMBER", - "gcp.pubsub.subscription.id" : "subscription-1-$GITHUB_RUN_NUMBER", + "gcp.pubsub.topic.id" : "$GCP_PUB_SUB_TOPIC", + "gcp.pubsub.subscription.id" : "$GCP_PUB_SUB_SUBSCRIPTION", "gcp.pubsub.credentials.path" : "/tmp/keyfile.json", "gcp.pubsub.proxy.url": "nginx_http2_proxy:8888", "confluent.topic.bootstrap.servers": "broker:9092", diff --git a/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh b/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh index 3f92611ff7..23e6c14da1 100755 --- a/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh +++ b/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh @@ -36,35 +36,37 @@ docker rm -f gcloud-config set -e docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cloud-sdk:latest gcloud auth activate-service-account --project ${GCP_PROJECT} --key-file /tmp/keyfile.json +GCP_PUB_SUB_TOPIC="topic-1-$GITHUB_RUN_NUMBER" +GCP_PUB_SUB_SUBSCRIPTION="subscription-1-$GITHUB_RUN_NUMBER" # cleanup if required set +e log "Delete topic and subscription, if required" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION set -e -log "Create a Pub/Sub topic called topic-1-$GITHUB_RUN_NUMBER" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create topic-1-$GITHUB_RUN_NUMBER +log "Create a Pub/Sub topic called $GCP_PUB_SUB_TOPIC" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics create $GCP_PUB_SUB_TOPIC -log "Create a Pub/Sub subscription called subscription-1-$GITHUB_RUN_NUMBER" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic topic-1-$GITHUB_RUN_NUMBER subscription-1-$GITHUB_RUN_NUMBER --ack-deadline 60 +log "Create a Pub/Sub subscription called $GCP_PUB_SUB_SUBSCRIPTION" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions create --topic $GCP_PUB_SUB_TOPIC $GCP_PUB_SUB_SUBSCRIPTION --ack-deadline 60 function cleanup_cloud_resources { set +e log "Delete GCP PubSub topic and subscription" check_if_continue - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete topic-1-$GITHUB_RUN_NUMBER-$GITHUB_RUN_NUMBER - docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete subscription-1-$GITHUB_RUN_NUMBER + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC + docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION docker rm -f gcloud-config } trap cleanup_cloud_resources EXIT -log "Publish three messages to topic-1-$GITHUB_RUN_NUMBER" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Peter" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Megan" -docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish topic-1-$GITHUB_RUN_NUMBER --message "Erin" +log "Publish three messages to $GCP_PUB_SUB_TOPIC" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish $GCP_PUB_SUB_TOPIC --message "Peter" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish $GCP_PUB_SUB_TOPIC --message "Megan" +docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics publish $GCP_PUB_SUB_TOPIC --message "Erin" sleep 10 @@ -75,8 +77,8 @@ playground connector create-or-update --connector pubsub-source << EOF "tasks.max" : "1", "kafka.topic" : "pubsub-topic", "gcp.pubsub.project.id" : "$GCP_PROJECT", - "gcp.pubsub.topic.id" : "topic-1-$GITHUB_RUN_NUMBER", - "gcp.pubsub.subscription.id" : "subscription-1-$GITHUB_RUN_NUMBER", + "gcp.pubsub.topic.id" : "$GCP_PUB_SUB_TOPIC", + "gcp.pubsub.subscription.id" : "$GCP_PUB_SUB_SUBSCRIPTION", "gcp.pubsub.credentials.path" : "/tmp/keyfile.json", "confluent.topic.bootstrap.servers": "broker:9092", "confluent.topic.replication.factor": "1", diff --git a/reproduction-models b/reproduction-models index 9a4ac8c7dc..e5cddd1cfb 160000 --- a/reproduction-models +++ b/reproduction-models @@ -1 +1 @@ -Subproject commit 9a4ac8c7dcf78c7e690cf2c47ea5b9ce6380a588 +Subproject commit e5cddd1cfbddee7bf945fee59b4429d037364143 From 29fb65bb42c313c63010ef3134e8c80bcaa0db10 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Feb 2025 16:04:49 +0100 Subject: [PATCH 217/659] minor --- .../fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh | 4 ++-- .../connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh | 4 ++-- .../gcp-google-pubsub-source.sh | 4 ++-- .../gcp-pubsub-source-nginx-proxy.sh | 4 ++-- connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh b/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh index 9eb06443e8..00f2349766 100755 --- a/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh +++ b/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh @@ -48,7 +48,7 @@ docker run -i -v ${GCP_KEYFILE}:/tmp/keyfile.json --name gcloud-config google/cl # cleanup if required set +e -log "Delete topic and subscription, if required" +log "Delete topic $GCP_PUB_SUB_TOPIC and subscription $GCP_PUB_SUB_SUBSCRIPTION, if required" docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION set -e @@ -61,7 +61,7 @@ docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub function cleanup_cloud_resources { set +e - log "Delete GCP PubSub topic and subscription" + log "Delete GCP PubSub topic $GCP_PUB_SUB_TOPIC and subscription $GCP_PUB_SUB_SUBSCRIPTION" check_if_continue docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION diff --git a/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh b/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh index 907de176f5..e2dc75dce5 100755 --- a/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh +++ b/connect/connect-gcp-google-pubsub-sink/gcp-google-pubsub-sink.sh @@ -57,7 +57,7 @@ GCP_PUB_SUB_SUBSCRIPTION="subscription-1-$GITHUB_RUN_NUMBER" # cleanup if required set +e -log "Delete topic and subscription, if required" +log "Delete topic $GCP_PUB_SUB_TOPIC and subscription $GCP_PUB_SUB_SUBSCRIPTION, if required" docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION set -e @@ -70,7 +70,7 @@ docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub function cleanup_cloud_resources { set +e - log "Delete GCP PubSub topic and subscription" + log "Delete GCP PubSub topic $GCP_PUB_SUB_TOPIC and subscription $GCP_PUB_SUB_SUBSCRIPTION" check_if_continue docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION diff --git a/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh b/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh index 8eaac072e5..7dcec4343c 100755 --- a/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh +++ b/connect/connect-gcp-google-pubsub-source/gcp-google-pubsub-source.sh @@ -57,7 +57,7 @@ GCP_PUB_SUB_SUBSCRIPTION="subscription-1-$GITHUB_RUN_NUMBER" # cleanup if required set +e -log "Delete topic and subscription, if required" +log "Delete topic $GCP_PUB_SUB_TOPIC and subscription $GCP_PUB_SUB_SUBSCRIPTION, if required" docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION set -e @@ -70,7 +70,7 @@ docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub function cleanup_cloud_resources { set +e - log "Delete GCP PubSub topic and subscription" + log "Delete GCP PubSub topic $GCP_PUB_SUB_TOPIC and subscription $GCP_PUB_SUB_SUBSCRIPTION" check_if_continue docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION diff --git a/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh b/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh index 22564d292e..000e83ca8b 100755 --- a/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh +++ b/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh @@ -47,7 +47,7 @@ GCP_PUB_SUB_SUBSCRIPTION="subscription-1-$GITHUB_RUN_NUMBER" # cleanup if required set +e -log "Delete topic and subscription, if required" +log "Delete topic $GCP_PUB_SUB_TOPIC and subscription $GCP_PUB_SUB_SUBSCRIPTION, if required" docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION set -e @@ -60,7 +60,7 @@ docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub function cleanup_cloud_resources { set +e - log "Delete GCP PubSub topic and subscription" + log "Delete GCP PubSub topic $GCP_PUB_SUB_TOPIC and subscription $GCP_PUB_SUB_SUBSCRIPTION" check_if_continue docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION diff --git a/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh b/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh index 23e6c14da1..863a87330f 100755 --- a/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh +++ b/connect/connect-gcp-pubsub-source/gcp-pubsub-source.sh @@ -41,7 +41,7 @@ GCP_PUB_SUB_SUBSCRIPTION="subscription-1-$GITHUB_RUN_NUMBER" # cleanup if required set +e -log "Delete topic and subscription, if required" +log "Delete topic $GCP_PUB_SUB_TOPIC and subscription $GCP_PUB_SUB_SUBSCRIPTION, if required" docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION set -e @@ -54,7 +54,7 @@ docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub function cleanup_cloud_resources { set +e - log "Delete GCP PubSub topic and subscription" + log "Delete GCP PubSub topic $GCP_PUB_SUB_TOPIC and subscription $GCP_PUB_SUB_SUBSCRIPTION" check_if_continue docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} topics delete $GCP_PUB_SUB_TOPIC docker run -i --volumes-from gcloud-config google/cloud-sdk:latest gcloud pubsub --project ${GCP_PROJECT} subscriptions delete $GCP_PUB_SUB_SUBSCRIPTION From 966e85398c560cd2c5cfa61d5b76e4b33ce9c38b Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Feb 2025 17:40:09 +0100 Subject: [PATCH 218/659] =?UTF-8?q?=F0=9F=90=9B=20"flink=5Fconnectors"=20v?= =?UTF-8?q?ariable=20is=20not=20set=20during=20playground=20container=20re?= =?UTF-8?q?creat=20#6255?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 6 ++++++ scripts/cli/src/commands/container/recreate.sh | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/scripts/cli/playground b/scripts/cli/playground index 50fafb88d8..2698f31b08 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -19674,6 +19674,12 @@ playground_container_recreate_command() { exit 1 fi + enable_flink=$(playground state get flags.ENABLE_FLINK) + if [ "$enable_flink" != "1" ] + then + export flink_connectors="" + fi + get_environment_used if [[ "$environment" == "ccloud" ]] then diff --git a/scripts/cli/src/commands/container/recreate.sh b/scripts/cli/src/commands/container/recreate.sh index efd9cfbbfb..ca36af1b17 100644 --- a/scripts/cli/src/commands/container/recreate.sh +++ b/scripts/cli/src/commands/container/recreate.sh @@ -18,6 +18,12 @@ then exit 1 fi +enable_flink=$(playground state get flags.ENABLE_FLINK) +if [ "$enable_flink" != "1" ] +then + export flink_connectors="" +fi + get_environment_used if [[ "$environment" == "ccloud" ]] then From 05abdab9b4bbbb74ea6976beb324f00b90e86f7e Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Feb 2025 17:41:49 +0100 Subject: [PATCH 219/659] typo --- scripts/cli/playground | 2 +- scripts/cli/src/lib/utils_function.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 2698f31b08..0cded3a280 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -9286,7 +9286,7 @@ function stop_all() { function wait_container_ready() { CONNECT_CONTAINER=${1:-"connect"} - CONTROL_CENTER_CONTAINER={$1:-"control-center"} + CONTROL_CENTER_CONTAINER=${1:-"control-center"} MAX_WAIT=300 if [ ! -z $WAIT_FOR_CONTROL_CENTER ] diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 0515d1486a..aee26f87f6 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -1041,7 +1041,7 @@ function stop_all() { function wait_container_ready() { CONNECT_CONTAINER=${1:-"connect"} - CONTROL_CENTER_CONTAINER={$1:-"control-center"} + CONTROL_CENTER_CONTAINER=${1:-"control-center"} MAX_WAIT=300 if [ ! -z $WAIT_FOR_CONTROL_CENTER ] From 8183200192d7ba8db2d869492ee25c9f4993a0f4 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Feb 2025 17:51:15 +0100 Subject: [PATCH 220/659] retry --- .../fully-managed-azure-data-lake-storage-gen2-sink.sh | 10 ++++++++++ .../azure-data-lake-storage-gen2-sink.sh | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh b/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh index 77442d36a1..5193bc0a7a 100755 --- a/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh +++ b/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh @@ -55,6 +55,16 @@ AZURE_RESOURCE_GROUP_ID=$(az group show --name $AZURE_RESOURCE_GROUP | jq -r '.i set +e log "Registering active directory App $AZURE_AD_APP_NAME, it might fail if already exist" AZURE_DATALAKE_CLIENT_ID=$(az ad app create --display-name "$AZURE_AD_APP_NAME" --is-fallback-public-client false --sign-in-audience AzureADandPersonalMicrosoftAccount --query appId -o tsv) +if [ $? != 0 ] +then + log "Failed to create Azure AD App. Attempting to delete existing app and recreate." + EXISTING_APP_ID=$(az ad app list --display-name "$AZURE_AD_APP_NAME" --query "[0].appId" -o tsv) + if [ ! -z "$EXISTING_APP_ID" ] + then + az ad app delete --id "$EXISTING_APP_ID" + AZURE_DATALAKE_CLIENT_ID=$(az ad app create --display-name "$AZURE_AD_APP_NAME" --is-fallback-public-client false --sign-in-audience AzureADandPersonalMicrosoftAccount --query appId -o tsv) + fi +fi AZURE_DATALAKE_CLIENT_PASSWORD=$(az ad app credential reset --id $AZURE_DATALAKE_CLIENT_ID | jq -r '.password') set -e diff --git a/connect/connect-azure-data-lake-storage-gen2-sink/azure-data-lake-storage-gen2-sink.sh b/connect/connect-azure-data-lake-storage-gen2-sink/azure-data-lake-storage-gen2-sink.sh index 07977bfbcb..d8bfb105bc 100755 --- a/connect/connect-azure-data-lake-storage-gen2-sink/azure-data-lake-storage-gen2-sink.sh +++ b/connect/connect-azure-data-lake-storage-gen2-sink/azure-data-lake-storage-gen2-sink.sh @@ -55,6 +55,16 @@ AZURE_RESOURCE_GROUP_ID=$(az group show --name $AZURE_RESOURCE_GROUP | jq -r '.i set +e log "Registering active directory App $AZURE_AD_APP_NAME, it might fail if already exist" AZURE_DATALAKE_CLIENT_ID=$(az ad app create --display-name "$AZURE_AD_APP_NAME" --is-fallback-public-client false --sign-in-audience AzureADandPersonalMicrosoftAccount --query appId -o tsv) +if [ $? != 0 ] +then + log "Failed to create Azure AD App. Attempting to delete existing app and recreate." + EXISTING_APP_ID=$(az ad app list --display-name "$AZURE_AD_APP_NAME" --query "[0].appId" -o tsv) + if [ ! -z "$EXISTING_APP_ID" ] + then + az ad app delete --id "$EXISTING_APP_ID" + AZURE_DATALAKE_CLIENT_ID=$(az ad app create --display-name "$AZURE_AD_APP_NAME" --is-fallback-public-client false --sign-in-audience AzureADandPersonalMicrosoftAccount --query appId -o tsv) + fi +fi AZURE_DATALAKE_CLIENT_PASSWORD=$(az ad app credential reset --id $AZURE_DATALAKE_CLIENT_ID | jq -r '.password') set -e From 0f2099c72d70c5d4153c5ca53384d2d61cc42995 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 7 Feb 2025 11:34:53 +0100 Subject: [PATCH 221/659] wait_container_ready --- scripts/cli/playground | 5 +++++ scripts/cli/src/commands/container/restart.sh | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 0cded3a280..4ee777af7f 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -19804,6 +19804,11 @@ playground_container_restart_command() { log "Restarting docker container ${container}" docker restart ${container} + + if [[ ${container} == connect* ]] + then + wait_container_ready + fi } # :command.function diff --git a/scripts/cli/src/commands/container/restart.sh b/scripts/cli/src/commands/container/restart.sh index 9856c04b25..89bde50732 100644 --- a/scripts/cli/src/commands/container/restart.sh +++ b/scripts/cli/src/commands/container/restart.sh @@ -1,4 +1,9 @@ container="${args[--container]}" log "Restarting docker container ${container}" -docker restart ${container} \ No newline at end of file +docker restart ${container} + +if [[ ${container} == connect* ]] +then + wait_container_ready +fi \ No newline at end of file From 6a7d585848b5d8b97a4927396aeb6fc96c5aa277 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 7 Feb 2025 14:07:37 +0100 Subject: [PATCH 222/659] fm --- .../fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh b/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh index 00f2349766..dc68a56093 100755 --- a/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh +++ b/ccloud/fm-gcp-pubsub-source/fully-managed-gcp-pubsub-source.sh @@ -29,8 +29,8 @@ cd - bootstrap_ccloud_environment -GCP_PUB_SUB_TOPIC="topic-1-$GITHUB_RUN_NUMBER" -GCP_PUB_SUB_SUBSCRIPTION="subscription-1-$GITHUB_RUN_NUMBER" +GCP_PUB_SUB_TOPIC="topic-1-fm-$GITHUB_RUN_NUMBER" +GCP_PUB_SUB_SUBSCRIPTION="subscription-1-fm-$GITHUB_RUN_NUMBER" set +e playground topic delete --topic pubsub-topic From f6f4ac77ede113c5382295a5b6d27f859efae6c7 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 7 Feb 2025 14:17:40 +0100 Subject: [PATCH 223/659] Ensure the role assignment has been applied --- .../fully-managed-azure-data-lake-storage-gen2-sink.sh | 2 ++ .../azure-data-lake-storage-gen2-sink.sh | 3 +++ 2 files changed, 5 insertions(+) diff --git a/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh b/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh index 5193bc0a7a..1355f81f33 100755 --- a/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh +++ b/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh @@ -109,6 +109,8 @@ sleep 20 log "Assigning Storage Blob Data Owner role to Service Principal $SERVICE_PRINCIPAL_ID" az role assignment create --assignee $SERVICE_PRINCIPAL_ID --role "Storage Blob Data Owner" --scope $AZURE_RESOURCE_GROUP_ID +# Ensure the role assignment has been applied +sleep 30 bootstrap_ccloud_environment diff --git a/connect/connect-azure-data-lake-storage-gen2-sink/azure-data-lake-storage-gen2-sink.sh b/connect/connect-azure-data-lake-storage-gen2-sink/azure-data-lake-storage-gen2-sink.sh index d8bfb105bc..31cdb99c30 100755 --- a/connect/connect-azure-data-lake-storage-gen2-sink/azure-data-lake-storage-gen2-sink.sh +++ b/connect/connect-azure-data-lake-storage-gen2-sink/azure-data-lake-storage-gen2-sink.sh @@ -109,6 +109,9 @@ sleep 20 log "Assigning Storage Blob Data Owner role to Service Principal $SERVICE_PRINCIPAL_ID" az role assignment create --assignee $SERVICE_PRINCIPAL_ID --role "Storage Blob Data Owner" --scope $AZURE_RESOURCE_GROUP_ID +# Ensure the role assignment has been applied +sleep 30 + # generate data file for externalizing secrets sed -e "s|:AZURE_DATALAKE_CLIENT_ID:|$AZURE_DATALAKE_CLIENT_ID|g" \ -e "s|:AZURE_DATALAKE_CLIENT_PASSWORD:|$AZURE_DATALAKE_CLIENT_PASSWORD|g" \ From 7f3641edee6c26265b0c2edfc05db14830c5ba6a Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 10 Feb 2025 15:56:27 +0100 Subject: [PATCH 224/659] =?UTF-8?q?=F0=9F=A7=A0=20add=20playground=20schem?= =?UTF-8?q?a=20derive-schema=20command=20#6263?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/completions.bash | 900 +++++++++--------- scripts/cli/playground | 235 +++++ scripts/cli/playground.json | 21 + scripts/cli/playground.yaml | 29 + scripts/cli/src/bashly.yml | 38 + .../cli/src/commands/schema/derive-schema.sh | 90 ++ 6 files changed, 867 insertions(+), 446 deletions(-) create mode 100644 scripts/cli/src/commands/schema/derive-schema.sh diff --git a/scripts/cli/completions.bash b/scripts/cli/completions.bash index 67954c2481..f56748601d 100644 --- a/scripts/cli/completions.bash +++ b/scripts/cli/completions.bash @@ -32,35 +32,35 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'config open-ccloud-connector-in-browser automatically'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'connector open-ccloud-connector-in-browser'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; + *'config open-ccloud-connector-in-browser automatically'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + *'config open-ccloud-connector-in-browser browser'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'container set-environment-variables'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector offsets get-offsets-request-status'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'tcp-proxy toggle-writes-service'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'connector offsets get-offsets-request-status'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container set-environment-variables'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy toggle-writes-client'*'--connection-id') + *'tcp-proxy toggle-reads-service'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'tcp-proxy toggle-reads-service'*'--connection-id') + *'tcp-proxy toggle-writes-client'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; @@ -72,18 +72,14 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; - *'connector offsets get-offsets-request-status'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'tcp-proxy toggle-reads-client'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; *'connector open-ccloud-connector-in-browser'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tcp-proxy toggle-reads-client'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") - ;; - *'ec2 sync-repro-folder local-to-ec2'*'--instance') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; @@ -92,22 +88,26 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'connector show-config-parameters'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'connector offsets get-offsets-request-status'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; *'connector-plugin versions'*'--connector-plugin') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; - *'connector open-ccloud-connector-in-browser'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--browser --connector --help -c -h")" -- "$cur") + *'connector show-config-parameters'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'topic produce'*'--value-subject-name-strategy') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") ;; + *'connector open-ccloud-connector-in-browser'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--browser --connector --help -c -h")" -- "$cur") + ;; + *'connector create-or-update'*'--initial-state') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "RUNNING PAUSED STOPPED")" -- "$cur") ;; @@ -120,6 +120,10 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; + *'topic produce'*'--key-subject-name-strategy') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") + ;; + *'debug enable-remote-debugging'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -128,10 +132,6 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'topic produce'*'--key-subject-name-strategy') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") - ;; - *'config open-ccloud-connector-in-browser'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h automatically browser")" -- "$cur") ;; @@ -148,26 +148,26 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic set-schema-compatibility'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") - ;; - *'container set-environment-variables'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'config container-kill-all-before-run'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'topic set-schema-compatibility'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'ec2 sync-repro-folder local-to-ec2'*'-i') + *'ec2 sync-repro-folder ec2-to-local'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'ec2 sync-repro-folder ec2-to-local'*'-i') + *'ec2 sync-repro-folder local-to-ec2'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; + *'config container-kill-all-before-run'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + *'tcp-proxy toggle-accept-connections'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -180,46 +180,58 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --env --help --restore-original-values -c -h")" -- "$cur") ;; - *'connector offsets reset'*'--connector') + *'connector offsets alter'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector offsets alter'*'--connector') + *'connector offsets reset'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'ec2 sync-repro-folder local-to-ec2'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + *'connector select-config'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'ec2 sync-repro-folder ec2-to-local'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'connector select-config'*'--connector') + *'connector show-config-parameters'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector show-config-parameters'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'ec2 sync-repro-folder local-to-ec2'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'cleanup-cloud-resources'*'--resource') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure ccloud salesforce")" -- "$cur") + *'schema derive-schema'*'--schema-type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "AVRO JSON PROTOBUF")" -- "$cur") ;; - *'schema get-compatibility'*'--subject') + *'schema set-compatibility'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'schema set-compatibility'*'--subject') + *'schema get-compatibility'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; + *'cleanup-cloud-resources'*'--resource') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure ccloud salesforce")" -- "$cur") + ;; + *'connector create-or-update'*'--level') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; + *'connector offsets get'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'topic set-schema-compatibility'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + ;; + *'debug flight-recorder'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -228,70 +240,46 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector show-config-parameters'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-refresh --help --only-show-json --open --verbose -c -h -o -v")" -- "$cur") - ;; - *'topic produce'*'--compression-codec') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "gzip snappy lz4 zstd")" -- "$cur") ;; - *'topic set-schema-compatibility'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") - ;; - - *'connector offsets get'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'connector show-config-parameters'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-refresh --help --only-show-json --open --verbose -c -h -o -v")" -- "$cur") ;; *'topic get-number-records'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'tcp-proxy toggle-writes-service'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'container change-jdk'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'debug enable-remote-debugging'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container change-jdk'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'tcp-proxy toggle-writes-service'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; *'tcp-proxy delay'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'topic produce'*'--validate-config') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") - ;; - - *'debug block-traffic'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - *'tcp-proxy break'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'connector log-level'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'topic set-schema-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --topic --verbose -h -t -v")" -- "$cur") + *'topic produce'*'--validate-config') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") ;; *'tcp-proxy toggle-reads-service'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'topic display-consumer-offsets'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --verbose -h -v")" -- "$cur") - ;; - *'tcp-proxy toggle-writes-client'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; @@ -300,48 +288,60 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector-plugin search-jar'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") + *'debug block-traffic'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'update-version'*'--connector-zip') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") + *'connector log-level'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tcp-proxy toggle-reads-client'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'topic set-schema-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --topic --verbose -h -t -v")" -- "$cur") ;; - *'tools read-parquet-file'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") + *'topic display-consumer-offsets'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --verbose -h -v")" -- "$cur") ;; - *'update-version'*'--connector-jar') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") + *'tools read-parquet-file'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") ;; *'debug enable-remote-debugging'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'container change-jdk'*'--version') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "8 11 17 21 22")" -- "$cur") + *'tcp-proxy toggle-reads-client'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; *'debug flight-recorder'*'--action') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") ;; + *'connector show-lag'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'container change-jdk'*'--version') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "8 11 17 21 22")" -- "$cur") + ;; + + *'connector-plugin search-jar'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") + ;; + *'connector snippets'*'--converter') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "avro protobuf json-schema json json-schema-enabled string bytearray")" -- "$cur") ;; - *'connector show-lag'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'update-version'*'--connector-jar') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") ;; - *'connector restart'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'update-version'*'--connector-zip') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") ;; *'connector create-or-update'*'-c') @@ -352,16 +352,12 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'debug thread-dump'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'container restart'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector restart'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug generate-diagnostics'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic consume'*'--value-subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; *'connector unpause'*'--connector') @@ -376,72 +372,64 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic consume'*'--value-subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'debug generate-diagnostics'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector update'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug thread-dump'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector status'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container restart'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector delete'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug block-traffic'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") ;; - *'connector resume'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug java-debug'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'connector-plugin versions'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; + *'connector update'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + *'connector-plugin search-jar'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--class --connector-plugin --connector-tag --help -c -h")" -- "$cur") ;; - *'container resume'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector status'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug block-traffic'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") + *'container resume'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug java-debug'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector resume'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'schema set-normalize'*'--value') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "true false")" -- "$cur") ;; - *'topic get-number-records'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") - ;; - - *'container get-ip-addresses'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - - *'container get-properties'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector delete'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'get-jmx-metrics'*'--container') + *'debug heap-dump'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug log-level set'*'--level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") - ;; - - *'debug heap-dump'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector pause'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'container pause'*'--container') @@ -452,39 +440,43 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'topic consume'*'--key-subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'connector create-or-update'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --initial-state --level --offsets --package --skip-automatic-connector-config --validate --verbose --wait-for-zero-lag -c -h -l -p -v")" -- "$cur") ;; *'connector log-level'*'--level') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'connector pause'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'topic consume'*'--key-subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + ;; + + *'tcp-proxy close-connection'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; *'tools read-avro-file'*'--file') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") ;; - *'connector create-or-update'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --initial-state --level --offsets --package --skip-automatic-connector-config --validate --verbose --wait-for-zero-lag -c -h -l -p -v")" -- "$cur") + *'topic get-number-records'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'tcp-proxy close-connection'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'debug log-level set'*'--level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'connector offsets alter'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container get-ip-addresses'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector offsets reset'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'get-jmx-metrics'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container logs'*'--container') + *'container get-properties'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -492,11 +484,11 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro --sink-only "$cur")")" -- "$cur") ;; - *'connector stop'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container logs'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy start'*'--hostname') + *'container kill'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; @@ -504,16 +496,44 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; + *'config check-repo-version'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + + *'container exec'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + *'repro bootstrap'*'--producer') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") ;; + *'debug tcp-dump'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + + *'connector stop'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'connector offsets alter'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'connector select-config'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'tcp-proxy start'*'--hostname') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + *'tcp-proxy get-connections'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'debug tcp-dump'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector offsets reset'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'ec2 create'*'--instance-type') @@ -524,35 +544,31 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") ;; - *'container exec'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector-plugin versions'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-plugin --force-refresh --help --last -c -h")" -- "$cur") ;; - *'container kill'*'--container') + *'container ssh'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector select-config'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'topic get-number-records'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") ;; - *'connector-plugin versions'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-plugin --force-refresh --help --last -c -h")" -- "$cur") + *'run'*'--cluster-environment') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-environment-list "$cur")")" -- "$cur") ;; - *'config check-repo-version'*) + *'config folder_zip_or_jar'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'schema set-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --subject --verbose -h -v")" -- "$cur") - ;; - - *'schema get-mode'*'--subject') + *'schema set-mode'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'schema set-mode'*'--subject') + *'schema get-mode'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; @@ -560,51 +576,43 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'schema get-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") - ;; - - *'schema register'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'schema set-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --subject --verbose -h -v")" -- "$cur") ;; - *'debug java-debug'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "enable disable")" -- "$cur") + *'schema get-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; *'remove-all-docker-images'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'container ssh'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'run'*'--cluster-environment') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-environment-list "$cur")")" -- "$cur") + *'schema register'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'topic get-number-records'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") + *'topic produce'*'--reference') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'config folder_zip_or_jar'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'debug java-debug'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "enable disable")" -- "$cur") ;; - *'topic produce'*'--reference') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + *'connector offsets alter'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'connector select-config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") + *'connector show-config'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'schema register'*'--schema') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + *'connector offsets reset'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'connector show-config'*'-c') + *'connector offsets get'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -612,150 +620,146 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--force --help --resource -h")" -- "$cur") ;; + *'connector select-config'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") + ;; + *'tools read-parquet-file'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'connector offsets alter'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'schema register'*'--schema') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; *'debug flight-recorder'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector offsets get'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'connector offsets reset'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'container change-jdk'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tools read-avro-file'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") + *'schema delete'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; *'debug java-debug'*'--type') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ssl_all ssl_handshake class_loading kerberos")" -- "$cur") ;; - *'schema delete'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'tools read-avro-file'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") ;; - *'container change-jdk'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'ec2 sync-repro-folder'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h ec2-to-local local-to-ec2")" -- "$cur") ;; - *'connector offsets get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'tcp-proxy start'*'--port') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'cleanup-cloud-details'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'repro bootstrap'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") ;; *'container exec'*'--shell') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'connector log-level'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") - ;; - - *'ec2 sync-repro-folder'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h ec2-to-local local-to-ec2")" -- "$cur") - ;; - *'connector show-config'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-rest-endpoint --help --verbose -c -h -v")" -- "$cur") ;; - *'repro bootstrap'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") + *'connector log-level'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tcp-proxy start'*'--port') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") + *'schema set-mode'*'--mode') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") ;; - *'debug block-traffic'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'cleanup-cloud-details'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + + *'connector offsets get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; *'topic describe'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'debug flight-recorder'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help -c -h")" -- "$cur") + *'connector log-level'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'connector log-level'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug log-level set'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'schema set-mode'*'--mode') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") + *'debug flight-recorder'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help -c -h")" -- "$cur") ;; - *'debug log-level set'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'debug block-traffic'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector show-lag'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'topic consume'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'topic produce'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'ec2 delete'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") - ;; - *'topic produce'*'--value') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'topic consume'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") - ;; - - *'schema set-normalize'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --value --verbose -h -v")" -- "$cur") - ;; - - *'container ssh'*'--shell') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") + *'ec2 delete'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") ;; *'tools read-avro-file'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'container change-jdk'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --version -c -h")" -- "$cur") + *'connector show-lag'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'schema derive-schema'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --payload --schema-type -h")" -- "$cur") ;; *'debug tcp-dump'*'--port') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'run'*'--cluster-region') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-kafka-region-list "$cur")")" -- "$cur") + *'schema set-normalize'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --value --verbose -h -v")" -- "$cur") ;; - *'connector log-level'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level -c -h -l")" -- "$cur") + *'container ssh'*'--shell') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") + ;; + + *'container change-jdk'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --version -c -h")" -- "$cur") ;; *'debug log-level set'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --level --package -h -l -p")" -- "$cur") ;; + *'connector restart'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + *'debug log-level get'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --package -h -p")" -- "$cur") ;; @@ -764,100 +768,80 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") ;; - *'update-version'*'--tag') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") + *'schema get'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + ;; + + *'connector log-level'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level -c -h -l")" -- "$cur") ;; *'debug block-traffic'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --destination --help --port -c -h")" -- "$cur") ;; + *'debug thread-dump'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + *'topic delete'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector unpause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'update-version'*'--tag') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") ;; - *'debug thread-dump'*'-c') + *'container restart'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector restart'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'ec2 start'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'schema get'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'run'*'--cluster-region') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-kafka-region-list "$cur")")" -- "$cur") ;; - *'ec2 start'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'connector unpause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'container unpause'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container restart'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - *'topic alter'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'container resume'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - *'connector resume'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector delete'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'connector show-lag'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --interval --max-wait --verbose -c -h -v")" -- "$cur") - ;; - - *'repro import'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") - ;; - - *'tools certs-create'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --output-folder --verbose -h -v")" -- "$cur") - ;; - *'ec2 stop'*'--instance') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'connector status'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'connector versions'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'debug java-debug'*'-c') + *'container resume'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector snippets'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--converter --dlq --help -h")" -- "$cur") - ;; - *'topic produce'*'--key') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'ec2 open'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'connector snippets'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--converter --dlq --help -h")" -- "$cur") ;; - *'connector update'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug java-debug'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'get-docker-compose'*) @@ -868,152 +852,176 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") ;; - *'connector versions'*) + *'connector status'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'container kill-all'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; + *'repro import'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") + ;; + *'container recreate'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --ignore-current-versions -h")" -- "$cur") ;; - *'container kill-all'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'connector delete'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'run'*'--connector-jar') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") ;; + *'tools certs-create'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --output-folder --verbose -h -v")" -- "$cur") + ;; + + *'connector show-lag'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --interval --max-wait --verbose -c -h -v")" -- "$cur") + ;; + + *'connector update'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + *'run'*'--cluster-cloud') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure")" -- "$cur") ;; - *'connector unpause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'ec2 open'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'connector plugins'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help --verbose -h -v")" -- "$cur") + *'run'*'--cluster-type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "basic standard dedicated")" -- "$cur") + ;; + + *'run'*'--cluster-name') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") ;; *'debug thread-dump'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'connector pause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'connector offsets'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter get get-offsets-request-status reset")" -- "$cur") ;; - *'repro bootstrap'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") + *'connector plugins'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help --verbose -h -v")" -- "$cur") ;; - *'container pause'*'-c') + *'container restart'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + ;; + + *'debug heap-dump'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector restart'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'connector pause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'repro bootstrap'*'-p') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") + *'container pause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector offsets'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter get get-offsets-request-status reset")" -- "$cur") + *'connector unpause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; *'container unpause'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'container restart'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") - ;; - - *'debug heap-dump'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector restart'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'run'*'--cluster-type') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "basic standard dedicated")" -- "$cur") + *'repro bootstrap'*'-p') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") ;; *'get-jmx-metrics'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'run'*'--cluster-name') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") + *'repro bootstrap'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") ;; - *'connector update'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") + *'container exec'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container logs'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'container resume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'topic describe'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'container kill'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'run'*'--environment') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") ;; - *'container resume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'connector resume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'config clipboard'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'connector delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + ;; + + *'container logs'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'connector stop'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container kill'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector status'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'container exec'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic describe'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'debug java-debug'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help --type -c -h")" -- "$cur") ;; - *'connector status'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") - ;; - - *'connector resume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'config clipboard'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'debug tcp-dump'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") - ;; - *'connector-plugin'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h search-jar versions")" -- "$cur") ;; + *'connector update'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") + ;; + *'connector pause'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'repro bootstrap'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--custom-smt --description --file --help --pipeline -d -f -h")" -- "$cur") + *'container ssh'*'-s') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; *'container pause'*) @@ -1024,80 +1032,72 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug heap-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") + *'schema set-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") ;; - *'topic produce'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'schema get-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; - *'debug log-level'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h get set")" -- "$cur") + *'tcp-proxy start'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --delay-service-response --help --hostname --port --service-response-corrupt --skip-automatic-connector-config --throttle-service-response -h")" -- "$cur") ;; - *'topic consume'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'schema register'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --metadata-property --schema --subject --verbose -h -v")" -- "$cur") ;; - *'tcp-proxy break'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") + *'topic consume'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'tcp-proxy delay'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") + *'repro bootstrap'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--custom-smt --description --file --help --pipeline -d -f -h")" -- "$cur") ;; - *'tcp-proxy start'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --delay-service-response --help --hostname --port --service-response-corrupt --skip-automatic-connector-config --throttle-service-response -h")" -- "$cur") + *'topic produce'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'get-jmx-metrics'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --domain --help --open -c -d -h -o")" -- "$cur") ;; - *'schema set-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") - ;; - - *'schema get-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") - ;; - - *'schema register'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --metadata-property --schema --subject --verbose -h -v")" -- "$cur") - ;; - - *'container ssh'*'-s') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") + *'debug log-level'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h get set")" -- "$cur") ;; - *'connector logs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") + *'debug heap-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") ;; - *'topic describe'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") + *'tcp-proxy delay'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") ;; - *'update-version'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-jar --connector-tag --connector-zip --help --tag -h")" -- "$cur") + *'tcp-proxy break'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") ;; *'container logs'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") ;; - *'container kill'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'debug tcp-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --duration --help --port -c -h")" -- "$cur") ;; *'container exec'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--command --container --help --root --shell -c -h")" -- "$cur") ;; - *'debug tcp-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --duration --help --port -c -h")" -- "$cur") + *'container kill'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + ;; + + *'topic describe'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") ;; *'connector stop'*) @@ -1108,22 +1108,22 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") ;; + *'connector logs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") + ;; + *'topic delete'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'--output-level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") + *'update-version'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-jar --connector-tag --connector-zip --help --tag -h")" -- "$cur") ;; *'schema delete'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --permanent --subject --verbose --version -h -v")" -- "$cur") ;; - *'topic consume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--grep --help --key-subject --max-characters --max-messages --min-expected-messages --plot-latencies-timestamp-field --tail --timeout --topic --value-subject --verbose -h -t -v")" -- "$cur") - ;; - *'get-ci-result'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -1132,22 +1132,30 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'container ssh'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") + *'--output-level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") + ;; + + *'debug testssl'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'topic alter'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'debug testssl'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'container ssh'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") ;; *'config editor'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; + *'topic consume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--grep --help --key-subject --max-characters --max-messages --min-expected-messages --plot-latencies-timestamp-field --tail --timeout --topic --value-subject --verbose -h -t -v")" -- "$cur") + ;; + *'topic produce'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --max-nb-messages-to-generate --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") ;; @@ -1160,10 +1168,6 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help -h")" -- "$cur") ;; - *'repro import'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") - ;; - *'topic delete'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --skip-delete-schema --topic --verbose -h -t -v")" -- "$cur") ;; @@ -1172,24 +1176,28 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --nb-partitions --topic --verbose -h -t -v")" -- "$cur") ;; - *'switch-back'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'repro import'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'ec2 start'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'switch-back'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'topic alter'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") ;; + *'ec2 start'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + ;; + *'ec2 open'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'ec2 create'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance-type --size --suffix -h")" -- "$cur") + *'schema get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") ;; *'topic list'*) @@ -1200,6 +1208,10 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; + *'ec2 create'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance-type --size --suffix -h")" -- "$cur") + ;; + *'open'*'--file') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") ;; @@ -1208,14 +1220,6 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'schema get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") - ;; - - *'container'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h change-jdk exec get-ip-addresses get-properties kill kill-all logs pause recreate restart resume set-environment-variables ssh unpause")" -- "$cur") - ;; - *'run'*'--file') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") ;; @@ -1224,43 +1228,39 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; + *'connector'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create-or-update delete log-level logs offsets open-ccloud-connector-in-browser open-docs pause plugins restart resume select-config show-config show-config-parameters show-lag snippets status stop unpause update versions")" -- "$cur") + ;; + *'open-docs'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") ;; - *'connector'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create-or-update delete log-level logs offsets open-ccloud-connector-in-browser open-docs pause plugins restart resume select-config show-config show-config-parameters show-lag snippets status stop unpause update versions")" -- "$cur") + *'container'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h change-jdk exec get-ip-addresses get-properties kill kill-all logs pause recreate restart resume set-environment-variables ssh unpause")" -- "$cur") ;; *'tcp-proxy'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h break close-all-connection-with-error close-connection delay get-connections start toggle-accept-connections toggle-reads-client toggle-reads-service toggle-writes-client toggle-writes-service")" -- "$cur") ;; - *'ec2 list'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'run'*'--tag') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") ;; - *'ec2 stop'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") - ;; - *'ec2 open'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--disable-sync-repro-folder --help --instance -h -i")" -- "$cur") ;; - *'history'*) + *'ec2 list'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'schema'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h delete get get-compatibility get-mode register set-compatibility set-mode set-normalize")" -- "$cur") + *'ec2 stop'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; - *'re-run'*) + *'history'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -1268,24 +1268,24 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") ;; - *'config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h check-repo-version clipboard container-kill-all-before-run editor folder_zip_or_jar open-ccloud-connector-in-browser")" -- "$cur") + *'status'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'status'*) + *'re-run'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'topic'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter consume create delete describe display-consumer-offsets get-number-records list produce set-schema-compatibility")" -- "$cur") + *'config'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h check-repo-version clipboard container-kill-all-before-run editor folder_zip_or_jar open-ccloud-connector-in-browser")" -- "$cur") ;; - *'run'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") + *'schema'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h delete derive-schema get get-compatibility get-mode register set-compatibility set-mode set-normalize")" -- "$cur") ;; - *'repro'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h bootstrap export import")" -- "$cur") + *'topic'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter consume create delete describe display-consumer-offsets get-number-records list produce set-schema-compatibility")" -- "$cur") ;; *'debug'*) @@ -1296,26 +1296,34 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h certs-create install-vscode-extension read-avro-file read-parquet-file")" -- "$cur") ;; - *'help'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'run'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") ;; - *'open'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") + *'repro'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h bootstrap export import")" -- "$cur") + ;; + + *'help'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; *'stop'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'ec2'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create delete list open start stop sync-repro-folder")" -- "$cur") + *'open'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; *'run'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--cluster-cloud --cluster-creds --cluster-environment --cluster-name --cluster-region --cluster-schema-registry-creds --cluster-type --connector-jar --connector-tag --connector-zip --enable-conduktor --enable-control-center --enable-flink --enable-jmx-grafana --enable-kcat --enable-ksqldb --enable-multiple-brokers --enable-multiple-connect-workers --enable-rest-proxy --enable-sql-datagen --environment --file --help --open --tag -f -h -o")" -- "$cur") ;; + *'ec2'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create delete list open start stop sync-repro-folder")" -- "$cur") + ;; + *'-o') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") ;; diff --git a/scripts/cli/playground b/scripts/cli/playground index 4ee777af7f..0c843fa427 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -70,6 +70,7 @@ playground_usage() { printf " %s 🔏 Set subject-level mode\n" "$(green "schema set-mode") " printf " %s 🧽 Set normalize at schema registry level\n" "$(green "schema set-normalize") " printf " %s 🧟 Delete schema\n" "$(green "schema delete") " + printf " %s 🔮 Derive a schema based on payload. \n" "$(green "schema derive-schema") " echo printf "%s\n" "$(bold "TCP Proxy commands:")" printf " %s 🏚 Zazkia TCP Proxy commands\n" "$(green "tcp-proxy") " @@ -2314,6 +2315,7 @@ playground_schema_usage() { printf " %s 🔏 Set subject-level mode\n" "$(green "set-mode") " printf " %s 🧽 Set normalize at schema registry level\n" "$(green "set-normalize") " printf " %s 🧟 Delete schema\n" "$(green "delete") " + printf " %s 🔮 Derive a schema based on payload. \n" "$(green "derive-schema") " echo # :command.long_usage @@ -2665,6 +2667,46 @@ playground_schema_delete_usage() { fi } +# :command.usage +playground_schema_derive_schema_usage() { + printf "playground schema derive-schema - 🔮 Derive a schema based on payload. \n\n" + + printf "%s\n" "$(bold "== Usage ==")" + printf " playground schema derive-schema [OPTIONS]\n" + printf " playground schema derive-schema --help | -h\n" + echo + + # :command.long_usage + if [[ -n "$long_usage" ]]; then + printf "%s\n" "$(bold "== Options ==")" + + # :command.usage_flags + # :flag.usage + printf " %s\n" "$(magenta "--payload PAYLOAD")" + printf " 📦 Payload to derive schema from\n" + printf " %s\n" "Default: -" + echo + + # :flag.usage + printf " %s\n" "$(magenta "--schema-type SCHEMA-TYPE")" + printf " 🧩 Schema Registry schema \"type\":\n \n - AVRO\n - JSON (json schema)\n - PROTOBUF\n \n Default is AVRO\n" + printf " %s\n" "Allowed: AVRO, JSON, PROTOBUF" + printf " %s\n" "Default: AVRO" + echo + + # :command.usage_fixed_flags + printf " %s\n" "$(magenta "--help, -h")" + printf " Show this help\n" + echo + + # :command.usage_examples + printf "%s\n" "$(bold "Examples")" + printf " playground schema derive-schema << EOF\n{\"name\": \"Foo\", \"Age\": {\"int\": 12}}\n{\"name\": \"Bar\", \"Age\": {\"string\": \"12\"}}\n{\"sport\": \"Football\"}\n{\"_id\":{\"key\":\"AA\"},\"duration\":{\"numberInt\":\"240\"},\"employeeNumber\":{\"numberInt\":\"12345\"},\"isActive\":\"Y\",\"plannedAbsenceKey\":\"AA\",\"startTimeMin\":{\"numberLong\":\"11599920\"}}\nEOF\n \n playground schema derive-schema --payload '{\"sport\": \"Football\"}'\n --schema-type PROTOBUF\n" +echo + +fi +} + # :command.usage playground_tcp_proxy_usage() { if [[ -n $long_usage ]]; then @@ -18591,6 +18633,102 @@ playground_schema_delete_command() { fi } +# :command.function +playground_schema_derive_schema_command() { + # src/commands/schema/derive-schema.sh + schema_type="${args[--schema-type]}" + payload="${args[--payload]}" + verbose="${args[--verbose]}" + + tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) + if [ -z "$PG_VERBOSE_MODE" ] + then + trap 'rm -rf $tmp_dir' EXIT + else + log "🐛📂 not deleting tmp dir $tmp_dir" + fi + + payload_file=$tmp_dir/payload_file + + if [ "$payload" = "-" ] + then + # stdin + if [ -t 0 ] + then + logerror "❌ stdin is empty you probably forgot to set --payload !" + exit 1 + else + payload_content=$(cat "$payload") + echo "$payload_content" > $payload_file + fi + else + if [[ $payload == @* ]] + then + # this is a payload file + argument_payload_file=$(echo "$payload" | cut -d "@" -f 2) + cp $argument_payload_file $payload_file + elif [ -f "$payload" ] + then + cp $payload $payload_file + else + payload_content=$payload + echo "$payload_content" > $payload_file + fi + fi + + LATEST_TAG=$(grep "export TAG" $root_folder/scripts/utils.sh | head -1 | cut -d "=" -f 2 | cut -d " " -f 1) + if [ -z "$LATEST_TAG" ] + then + logerror "❌ error while getting default TAG " + exit 1 + fi + + cat << EOF > $tmp_dir/pom.xml + + 4.0.0 + io.confluent.app + my-app + 1 + + + confluent + https://packages.confluent.io/maven/ + + + + + + io.confluent + kafka-schema-registry-maven-plugin + $LATEST_TAG + + /usr/src/mymaven/payload_file + $schema_type + /usr/src/mymaven/schema_file + + + + + +EOF + + set +e + log "🔮 Calling derive-schema maven plugin (see https://docs.confluent.io/platform/current/schema-registry/develop/maven-plugin.html#schema-registry-derive-schema)" + docker run -i --rm -v "${tmp_dir}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$root_folder/scripts/settings.xml:/tmp/settings.xml" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml io.confluent:kafka-schema-registry-maven-plugin:derive-schema > /tmp/result.log 2>&1 + if [ $? != 0 ] + then + logerror "❌ error while calling derive-schema" + tail -500 /tmp/result.log + exit 1 + fi + + set -e + log "🔮 Schema file generated at $tmp_dir/schema_file" + cat $tmp_dir/schema_file | jq -r '.schemas[]|del(.messagesMatched)|.schema' +} + # :command.function playground_tcp_proxy_start_command() { # src/commands/tcp-proxy/start.sh @@ -30503,6 +30641,13 @@ playground_schema_parse_requirements() { shift $# ;; + derive-schema) + action="derive-schema" + shift + playground_schema_derive_schema_parse_requirements "$@" + shift $# + ;; + # :command.command_fallback "") playground_schema_usage >&2 @@ -31423,6 +31568,95 @@ playground_schema_delete_parse_requirements() { } +# :command.parse_requirements +playground_schema_derive_schema_parse_requirements() { + # :command.fixed_flags_filter + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + --help | -h) + long_usage=yes + playground_schema_derive_schema_usage + exit + ;; + + *) + break + ;; + + esac + done + + # :command.command_filter + action="schema derive-schema" + + # :command.parse_requirements_while + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + # :flag.case + --payload) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + args['--payload']="$2" + shift + shift + else + printf "%s\n" "--payload requires an argument: --payload PAYLOAD" >&2 + exit 1 + fi + ;; + + # :flag.case + --schema-type) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + args['--schema-type']="$2" + shift + shift + else + printf "%s\n" "--schema-type requires an argument: --schema-type SCHEMA-TYPE" >&2 + exit 1 + fi + ;; + + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; + + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + printf "invalid argument: %s\n" "$key" >&2 + exit 1 + + ;; + + esac + done + + # :command.default_assignments + [[ -n ${args['--payload']:-} ]] || args['--payload']="-" + [[ -n ${args['--schema-type']:-} ]] || args['--schema-type']="AVRO" + + # :command.whitelist_filter + if [[ ${args['--schema-type']:-} ]] && [[ ! ${args['--schema-type']:-} =~ ^(AVRO|JSON|PROTOBUF)$ ]]; then + printf "%s\n" "--schema-type must be one of: AVRO, JSON, PROTOBUF" >&2 + exit 1 + fi + + # :command.user_filter + filter_error=$(filter_not_mdc_environment) + if [[ -n $filter_error ]]; then + echo "$filter_error" >&2 + exit 1 + fi + +} + # :command.parse_requirements playground_tcp_proxy_parse_requirements() { # :command.fixed_flags_filter @@ -39975,6 +40209,7 @@ run() { "schema set-mode") playground_schema_set_mode_command ;; "schema set-normalize") playground_schema_set_normalize_command ;; "schema delete") playground_schema_delete_command ;; + "schema derive-schema") playground_schema_derive_schema_command ;; "tcp-proxy") playground_tcp_proxy_command ;; "tcp-proxy start") playground_tcp_proxy_start_command ;; "tcp-proxy get-connections") playground_tcp_proxy_get_connections_command ;; diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index 201da97b4c..409a37d4ad 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -825,6 +825,27 @@ "description": "🐞 Show command being ran.\n" } ] + }, + { + "name": "derive-schema", + "description": "🔮 Derive a schema based on payload. \n", + "usage": "playground schema derive-schema [OPTIONS]", + "options": [ + { + "names": [ + "--payload" + ], + "argument": "PAYLOAD", + "description": "📦 Payload to derive schema from\n\nDefault value: -\n" + }, + { + "names": [ + "--schema-type" + ], + "argument": "AVRO", + "description": "🧩 Schema Registry schema \"type\":\n\n- AVRO\n- JSON (json schema)\n- PROTOBUF\n\nDefault is AVRO\n\nDefault value: AVRO\n\nAllowed values: AVRO, JSON, PROTOBUF\n" + } + ] } ] }, diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index 809d9dbb95..63b17967f4 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -957,6 +957,35 @@ subcommands: description: | 🐞 Show command being ran. + - name: derive-schema + description: | + 🔮 Derive a schema based on payload. + usage: playground schema derive-schema [OPTIONS] + options: + - names: + - --payload + argument: PAYLOAD + description: | + 📦 Payload to derive schema from + + Default value: - + + - names: + - --schema-type + argument: AVRO + description: | + 🧩 Schema Registry schema "type": + + - AVRO + - JSON (json schema) + - PROTOBUF + + Default is AVRO + + Default value: AVRO + + Allowed values: AVRO, JSON, PROTOBUF + - name: tcp-proxy description: | 🏚 Zazkia TCP Proxy commands diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index bda0e3d8e0..0bfb26532b 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -1395,6 +1395,44 @@ commands: 💀 Hard delete (default is soft delete) - *verbose + - name: derive-schema + group: Schema + filters: + - not_mdc_environment + help: |- + 🔮 Derive a schema based on payload. + flags: + - long: --payload + arg: payload + default: "-" + required: false + help: |- + 📦 Payload to derive schema from + - long: --schema-type + required: false + default: "AVRO" + arg: schema-type + help: |- + 🧩 Schema Registry schema "type": + + - AVRO + - JSON (json schema) + - PROTOBUF + + Default is AVRO + allowed: + - AVRO + - JSON + - PROTOBUF + examples: | + playground schema derive-schema << EOF + {"name": "Foo", "Age": {"int": 12}} + {"name": "Bar", "Age": {"string": "12"}} + {"sport": "Football"} + {"_id":{"key":"AA"},"duration":{"numberInt":"240"},"employeeNumber":{"numberInt":"12345"},"isActive":"Y","plannedAbsenceKey":"AA","startTimeMin":{"numberLong":"11599920"}} + EOF + + playground schema derive-schema --payload '{"sport": "Football"}' --schema-type PROTOBUF - name: tcp-proxy expose: always diff --git a/scripts/cli/src/commands/schema/derive-schema.sh b/scripts/cli/src/commands/schema/derive-schema.sh new file mode 100644 index 0000000000..84fa369661 --- /dev/null +++ b/scripts/cli/src/commands/schema/derive-schema.sh @@ -0,0 +1,90 @@ +schema_type="${args[--schema-type]}" +payload="${args[--payload]}" +verbose="${args[--verbose]}" + +tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) +if [ -z "$PG_VERBOSE_MODE" ] +then + trap 'rm -rf $tmp_dir' EXIT +else + log "🐛📂 not deleting tmp dir $tmp_dir" +fi + +payload_file=$tmp_dir/payload_file + +if [ "$payload" = "-" ] +then + # stdin + if [ -t 0 ] + then + logerror "❌ stdin is empty you probably forgot to set --payload !" + exit 1 + else + payload_content=$(cat "$payload") + echo "$payload_content" > $payload_file + fi +else + if [[ $payload == @* ]] + then + # this is a payload file + argument_payload_file=$(echo "$payload" | cut -d "@" -f 2) + cp $argument_payload_file $payload_file + elif [ -f "$payload" ] + then + cp $payload $payload_file + else + payload_content=$payload + echo "$payload_content" > $payload_file + fi +fi + +LATEST_TAG=$(grep "export TAG" $root_folder/scripts/utils.sh | head -1 | cut -d "=" -f 2 | cut -d " " -f 1) +if [ -z "$LATEST_TAG" ] +then + logerror "❌ error while getting default TAG " + exit 1 +fi + +cat << EOF > $tmp_dir/pom.xml + + 4.0.0 + io.confluent.app + my-app + 1 + + + confluent + https://packages.confluent.io/maven/ + + + + + + io.confluent + kafka-schema-registry-maven-plugin + $LATEST_TAG + + /usr/src/mymaven/payload_file + $schema_type + /usr/src/mymaven/schema_file + + + + + +EOF + +set +e +log "🔮 Calling derive-schema maven plugin (see https://docs.confluent.io/platform/current/schema-registry/develop/maven-plugin.html#schema-registry-derive-schema)" +docker run -i --rm -v "${tmp_dir}":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$root_folder/scripts/settings.xml:/tmp/settings.xml" -w /usr/src/mymaven maven:3.6.1-jdk-11 mvn -s /tmp/settings.xml io.confluent:kafka-schema-registry-maven-plugin:derive-schema > /tmp/result.log 2>&1 +if [ $? != 0 ] +then + logerror "❌ error while calling derive-schema" + tail -500 /tmp/result.log + exit 1 +fi + +set -e +log "🔮 Schema file generated at $tmp_dir/schema_file" +cat $tmp_dir/schema_file | jq -r '.schemas[]|del(.messagesMatched)|.schema' \ No newline at end of file From 361be79b9a205d525199dc188c52bb6b7d63e5f3 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 11 Feb 2025 10:15:25 +0100 Subject: [PATCH 225/659] typo --- connect/connect-jdbc-mysql-sink/mysql-sink.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/connect/connect-jdbc-mysql-sink/mysql-sink.sh b/connect/connect-jdbc-mysql-sink/mysql-sink.sh index 1f2ce4c640..3b0336c2d7 100755 --- a/connect/connect-jdbc-mysql-sink/mysql-sink.sh +++ b/connect/connect-jdbc-mysql-sink/mysql-sink.sh @@ -22,8 +22,7 @@ playground connector create-or-update --connector mysql-sink << EOF "tasks.max": "1", "connection.url": "jdbc:mysql://mysql:3306/db?user=user&password=password&useSSL=false", "topics": "orders", - "auto.create": "true", - "consumer.override.enable.auto.commit": "false" + "auto.create": "true" } EOF From 524b4f1ad37e76e48052dcf0f88bf3877a806c6e Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 11 Feb 2025 10:51:59 +0100 Subject: [PATCH 226/659] 7.8.1 --- connect/connect-syslog-source/syslog.sh | 2 +- scripts/cli/tag-list.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/connect/connect-syslog-source/syslog.sh b/connect/connect-syslog-source/syslog.sh index 56c5b9b7d3..f62250b6c3 100755 --- a/connect/connect-syslog-source/syslog.sh +++ b/connect/connect-syslog-source/syslog.sh @@ -24,7 +24,7 @@ EOF sleep 10 log "Test with sample syslog-formatted message sent via netcat" -echo "<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - Your refrigerator is running" | docker run -i --rm --network=host subfuzion/netcat -v -w 0 localhost 5454 +echo "<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - Your refrigerator is running" | nc -v -w 0 localhost 5454 sleep 5 diff --git a/scripts/cli/tag-list.txt b/scripts/cli/tag-list.txt index f01095e5a3..e9e91722d5 100644 --- a/scripts/cli/tag-list.txt +++ b/scripts/cli/tag-list.txt @@ -185,3 +185,4 @@ 7.7.1 7.7.2 7.8.0 +7.8.1 From aa84e93bca4e43e73644d07510bf7f37c5143b2f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 11 Feb 2025 10:52:09 +0100 Subject: [PATCH 227/659] =?UTF-8?q?=F0=9F=90=9B=20remove=20netcat=20requir?= =?UTF-8?q?ement=20in=20get=5Fconnect=5Furl=5Fand=5Fsecurity()=20#6267?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 4 ++++ scripts/cli/src/lib/utils_function.sh | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/scripts/cli/playground b/scripts/cli/playground index 0c843fa427..f544b95f26 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -9046,6 +9046,10 @@ function get_connect_image() { fi } +function nc() { + docker run -i --rm --network=host subfuzion/netcat "$@" +} + function az() { docker run --quiet --rm -v /tmp:/tmp -v $HOME/.azure:/home/az/.azure -e HOME=/home/az --rm -i mcr.microsoft.com/azure-cli:cbl-mariner2.0 az "$@" } diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index aee26f87f6..1cc80e6332 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -759,6 +759,10 @@ function get_connect_image() { fi } +function nc() { + docker run -i --rm --network=host subfuzion/netcat "$@" +} + function az() { docker run --quiet --rm -v /tmp:/tmp -v $HOME/.azure:/home/az/.azure -e HOME=/home/az --rm -i mcr.microsoft.com/azure-cli:cbl-mariner2.0 az "$@" } From c92ca62b1556f787994a667bff0bd3c14327476b Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 11 Feb 2025 10:54:51 +0100 Subject: [PATCH 228/659] =?UTF-8?q?=F0=9F=91=BE=20Update=20default=20TAG?= =?UTF-8?q?=20to=207.8.1=20#6268?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 6 +++--- .github/workflows/update-readme.yml | 2 +- scripts/utils.sh | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 56009377b6..5a3e8ede55 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: strategy: fail-fast: false matrix: - tag: ["7.8.0"] + tag: ["7.8.1"] test_list : [ # requiring ngrok "🚀1️⃣ ccloud/fm-debezium-mysql-legacy-source ccloud/fm-debezium-postgresql-legacy-source ccloud/fm-debezium-mysql-v2-source ccloud/fm-debezium-sqlserver-legacy-source ccloud/fm-debezium-sqlserver-v2-source ccloud/fm-elasticsearch-sink ccloud/fm-jdbc-sqlserver-sink ccloud/fm-jdbc-sqlserver-source ccloud/fm-ibm-mq-source ccloud/fm-jdbc-mysql-source ccloud/fm-jdbc-postgresql-sink ccloud/fm-mqtt-source ccloud/fm-debezium-postgresql-v2-source ccloud/fm-jdbc-postgresql-source", @@ -329,7 +329,7 @@ jobs: strategy: fail-fast: false matrix: - tag: ["7.8.0"] + tag: ["7.8.1"] test_list : [ "🚀 ${{ github.event.inputs.test_name }}" ] @@ -607,7 +607,7 @@ jobs: - name: Update README run: | cd ./scripts/cli - ./playground update-readme --tags "7.8.0" + ./playground update-readme --tags "7.8.1" env: GH_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml index fd6b672131..513589936f 100644 --- a/.github/workflows/update-readme.yml +++ b/.github/workflows/update-readme.yml @@ -26,7 +26,7 @@ jobs: - name: Update README run: | cd ./scripts/cli - ./playground update-readme --tags "7.6.1" + ./playground update-readme --tags "7.8.1" env: GH_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} diff --git a/scripts/utils.sh b/scripts/utils.sh index 2cef244458..1d19260549 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -33,7 +33,7 @@ fi if [ -z "$TAG" ] then # TAG is not set, use default: - export TAG=7.8.0 # default tag + export TAG=7.8.1 # default tag # to handle ubi8 images export TAG_BASE=$TAG if [ -z "$CP_KAFKA_IMAGE" ] From a47c3e28b1d08830dfda28dff6fb1511ec2ff24a Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 11 Feb 2025 13:29:11 +0100 Subject: [PATCH 229/659] set back --- connect/connect-syslog-source/syslog.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connect/connect-syslog-source/syslog.sh b/connect/connect-syslog-source/syslog.sh index f62250b6c3..56c5b9b7d3 100755 --- a/connect/connect-syslog-source/syslog.sh +++ b/connect/connect-syslog-source/syslog.sh @@ -24,7 +24,7 @@ EOF sleep 10 log "Test with sample syslog-formatted message sent via netcat" -echo "<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - Your refrigerator is running" | nc -v -w 0 localhost 5454 +echo "<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - Your refrigerator is running" | docker run -i --rm --network=host subfuzion/netcat -v -w 0 localhost 5454 sleep 5 From 6eeb96838480a2f77f7b2441b544e3b7f8b6776a Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 11 Feb 2025 14:01:16 +0100 Subject: [PATCH 230/659] =?UTF-8?q?=F0=9F=90=9B=20remove=20netcat=20requir?= =?UTF-8?q?ement=20in=20get=5Fconnect=5Furl=5Fand=5Fsecurity()=20#6267?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 19 +++++++++++-------- scripts/cli/src/lib/cli_function.sh | 15 +++++++++++---- scripts/cli/src/lib/utils_function.sh | 4 ---- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index f544b95f26..2bc2d969a9 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -6454,25 +6454,32 @@ function get_environment_used() { environment=$(playground state get run.environment) } +function is_container_running() { + container_name=$1 + docker inspect -f '{{.State.Running}}' "$container_name" 2>/dev/null | grep -q "true" +} + function get_connect_url_and_security() { get_environment_used connect_port="8083" - if ! nc -vz localhost 8083 > /dev/null 2>&1 + + if ! is_container_running "connect" then - if nc -vz localhost 8283 > /dev/null 2>&1 + if is_container_running "connect2" then connect_port="8283" # log "💫 using connect rest api for connect2 as connect rest api on port 8083 is not available" - elif nc -vz localhost 8383 > /dev/null 2>&1 + elif is_container_running "connect3" then connect_port="8383" # log "💫 using connect rest api for connect3 as connect rest api on port 8083 and connect2 rest api on port 8283 are not available" else - logerror "❌ No available port found for connect rest api" + logerror "❌ No available port found for connect rest api, none of containers connect, connect2 or connect3 are running!" exit 1 fi fi + connect_url="http://localhost:$connect_port" security="" @@ -9046,10 +9053,6 @@ function get_connect_image() { fi } -function nc() { - docker run -i --rm --network=host subfuzion/netcat "$@" -} - function az() { docker run --quiet --rm -v /tmp:/tmp -v $HOME/.azure:/home/az/.azure -e HOME=/home/az --rm -i mcr.microsoft.com/azure-cli:cbl-mariner2.0 az "$@" } diff --git a/scripts/cli/src/lib/cli_function.sh b/scripts/cli/src/lib/cli_function.sh index 87b46dd7bf..a6fe6d1aec 100644 --- a/scripts/cli/src/lib/cli_function.sh +++ b/scripts/cli/src/lib/cli_function.sh @@ -2,25 +2,32 @@ function get_environment_used() { environment=$(playground state get run.environment) } +function is_container_running() { + container_name=$1 + docker inspect -f '{{.State.Running}}' "$container_name" 2>/dev/null | grep -q "true" +} + function get_connect_url_and_security() { get_environment_used connect_port="8083" - if ! nc -vz localhost 8083 > /dev/null 2>&1 + + if ! is_container_running "connect" then - if nc -vz localhost 8283 > /dev/null 2>&1 + if is_container_running "connect2" then connect_port="8283" # log "💫 using connect rest api for connect2 as connect rest api on port 8083 is not available" - elif nc -vz localhost 8383 > /dev/null 2>&1 + elif is_container_running "connect3" then connect_port="8383" # log "💫 using connect rest api for connect3 as connect rest api on port 8083 and connect2 rest api on port 8283 are not available" else - logerror "❌ No available port found for connect rest api" + logerror "❌ No available port found for connect rest api, none of containers connect, connect2 or connect3 are running!" exit 1 fi fi + connect_url="http://localhost:$connect_port" security="" diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 1cc80e6332..aee26f87f6 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -759,10 +759,6 @@ function get_connect_image() { fi } -function nc() { - docker run -i --rm --network=host subfuzion/netcat "$@" -} - function az() { docker run --quiet --rm -v /tmp:/tmp -v $HOME/.azure:/home/az/.azure -e HOME=/home/az --rm -i mcr.microsoft.com/azure-cli:cbl-mariner2.0 az "$@" } From ae40da0b5568c25db77382a46036037cb0f64fba Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 11 Feb 2025 14:58:49 +0100 Subject: [PATCH 231/659] =?UTF-8?q?=F0=9F=A7=A0=20Add=20derive-schema=20op?= =?UTF-8?q?tion=20to=20playground=20topic=20produce=20#6269?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/completions.bash | 880 +++++++++--------- scripts/cli/playground | 99 +- scripts/cli/playground.json | 24 +- scripts/cli/playground.yaml | 30 +- scripts/cli/src/bashly.yml | 46 +- .../cli/src/commands/schema/derive-schema.sh | 2 +- scripts/cli/src/commands/topic/produce.sh | 36 + 7 files changed, 659 insertions(+), 458 deletions(-) diff --git a/scripts/cli/completions.bash b/scripts/cli/completions.bash index f56748601d..b4f4624c04 100644 --- a/scripts/cli/completions.bash +++ b/scripts/cli/completions.bash @@ -44,40 +44,40 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector offsets get-offsets-request-status'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container set-environment-variables'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'tcp-proxy toggle-writes-service'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'container set-environment-variables'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector offsets get-offsets-request-status'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tcp-proxy toggle-reads-service'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + *'connector-plugin search-jar'*'--connector-plugin') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; *'tcp-proxy toggle-writes-client'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'connector-plugin search-jar'*'--connector-plugin') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") - ;; - *'topic set-schema-compatibility'*'--compatibility') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; + *'tcp-proxy toggle-reads-service'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + ;; + *'tcp-proxy toggle-reads-client'*'--connection-id') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'connector open-ccloud-connector-in-browser'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'connector offsets get-offsets-request-status'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; *'ec2 sync-repro-folder local-to-ec2'*'--instance') @@ -88,8 +88,8 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'connector offsets get-offsets-request-status'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'connector open-ccloud-connector-in-browser'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'connector-plugin versions'*'--connector-plugin') @@ -100,16 +100,12 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'topic produce'*'--value-subject-name-strategy') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") - ;; - *'connector open-ccloud-connector-in-browser'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--browser --connector --help -c -h")" -- "$cur") ;; - *'connector create-or-update'*'--initial-state') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "RUNNING PAUSED STOPPED")" -- "$cur") + *'topic produce'*'--value-subject-name-strategy') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") ;; *'tcp-proxy close-all-connection-with-error'*) @@ -120,16 +116,20 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'topic produce'*'--key-subject-name-strategy') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") + *'connector create-or-update'*'--initial-state') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "RUNNING PAUSED STOPPED")" -- "$cur") + ;; + + *'tcp-proxy get-connections'*'--connection-id') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; *'debug enable-remote-debugging'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy get-connections'*'--connection-id') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") + *'topic produce'*'--key-subject-name-strategy') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "TopicNameStrategy RecordNameStrategy TopicRecordNameStrategy")" -- "$cur") ;; *'config open-ccloud-connector-in-browser'*) @@ -156,6 +156,14 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; + *'topic produce'*'--derive-value-schema-as') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "AVRO JSON PROTOBUF")" -- "$cur") + ;; + + *'config container-kill-all-before-run'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + *'ec2 sync-repro-folder ec2-to-local'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; @@ -164,8 +172,8 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'config container-kill-all-before-run'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'container set-environment-variables'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --env --help --restore-original-values -c -h")" -- "$cur") ;; *'tcp-proxy toggle-accept-connections'*) @@ -176,52 +184,56 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container set-environment-variables'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --env --help --restore-original-values -c -h")" -- "$cur") - ;; - - *'connector offsets alter'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'topic produce'*'--derive-key-schema-as') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "AVRO JSON PROTOBUF")" -- "$cur") ;; - *'connector offsets reset'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'ec2 sync-repro-folder ec2-to-local'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; *'connector select-config'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'ec2 sync-repro-folder ec2-to-local'*) + *'ec2 sync-repro-folder local-to-ec2'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; + *'connector offsets alter'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + *'connector show-config-parameters'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'ec2 sync-repro-folder local-to-ec2'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + *'connector offsets reset'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'schema derive-schema'*'--schema-type') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "AVRO JSON PROTOBUF")" -- "$cur") + *'schema get-compatibility'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; *'schema set-compatibility'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'schema get-compatibility'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'schema derive-schema'*'--schema-type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "AVRO JSON PROTOBUF")" -- "$cur") + ;; + + *'connector create-or-update'*'--level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; *'cleanup-cloud-resources'*'--resource') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure ccloud salesforce")" -- "$cur") ;; - *'connector create-or-update'*'--level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'connector show-config'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'connector offsets get'*'--connector') @@ -232,36 +244,40 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'debug flight-recorder'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector show-config-parameters'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-refresh --help --only-show-json --open --verbose -c -h -o -v")" -- "$cur") ;; - *'connector show-config'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug flight-recorder'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'topic produce'*'--compression-codec') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "gzip snappy lz4 zstd")" -- "$cur") ;; - *'connector show-config-parameters'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-refresh --help --only-show-json --open --verbose -c -h -o -v")" -- "$cur") + *'container change-jdk'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + + *'tcp-proxy toggle-writes-service'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; *'topic get-number-records'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'container change-jdk'*'--container') + *'debug enable-remote-debugging'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug enable-remote-debugging'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic produce'*'--validate-config') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") ;; - *'tcp-proxy toggle-writes-service'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'debug block-traffic'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'tcp-proxy delay'*'--connection-id') @@ -272,24 +288,12 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zazkia-connection-list)")" -- "$cur") ;; - *'topic produce'*'--validate-config') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "scrub.invalid.names=true enhanced.avro.schema.support=true connect.meta.data=false object.additional.properties=false use.optional.for.nonrequired=true ignore.default.for.nullables=true generalized.sum.type.support=true enhanced.protobuf.schema.support=true generate.index.for.unions=false int.for.enums=true optional.for.nullables=true generate.struct.for.nulls=true wrapper.for.nullables=true wrapper.for.raw.primitives=false")" -- "$cur") - ;; - - *'tcp-proxy toggle-reads-service'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") - ;; - - *'tcp-proxy toggle-writes-client'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") - ;; - *'tools install-vscode-extension'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'debug block-traffic'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'tcp-proxy toggle-reads-service'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; *'connector log-level'*'--connector') @@ -304,36 +308,24 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --verbose -h -v")" -- "$cur") ;; - *'tools read-parquet-file'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") + *'tcp-proxy toggle-writes-client'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; *'debug enable-remote-debugging'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'tcp-proxy toggle-reads-client'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") - ;; - - *'debug flight-recorder'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") - ;; - - *'connector show-lag'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - - *'container change-jdk'*'--version') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "8 11 17 21 22")" -- "$cur") + *'tools read-parquet-file'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") ;; *'connector-plugin search-jar'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; - *'connector snippets'*'--converter') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "avro protobuf json-schema json json-schema-enabled string bytearray")" -- "$cur") + *'tcp-proxy toggle-reads-client'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; *'update-version'*'--connector-jar') @@ -344,296 +336,316 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") ;; - *'connector create-or-update'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug flight-recorder'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") ;; - *'connector create-or-update'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'connector show-lag'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector restart'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'connector snippets'*'--converter') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "avro protobuf json-schema json json-schema-enabled string bytearray")" -- "$cur") ;; - *'topic consume'*'--value-subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'container change-jdk'*'--version') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "8 11 17 21 22")" -- "$cur") ;; - *'connector unpause'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container unpause'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'topic produce'*'--compatibility') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "BACKWARD BACKWARD_TRANSITIVE FORWARD FORWARD_TRANSITIVE FULL FULL_TRANSITIVE NONE")" -- "$cur") ;; - *'container unpause'*'--container') + *'container restart'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug generate-diagnostics'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector create-or-update'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; *'debug thread-dump'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container restart'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'topic consume'*'--value-subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'debug block-traffic'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") + *'connector restart'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug java-debug'*'--container') + *'debug generate-diagnostics'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector-plugin versions'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") - ;; - - *'connector update'*'--connector') + *'connector create-or-update'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector-plugin search-jar'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--class --connector-plugin --connector-tag --help -c -h")" -- "$cur") + *'connector unpause'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'connector status'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'container resume'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector-plugin versions'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-plugin "$cur")")" -- "$cur") ;; - *'connector resume'*'--connector') + *'connector update'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'schema set-normalize'*'--value') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "true false")" -- "$cur") + *'container resume'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'connector delete'*'--connector') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'debug heap-dump'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector resume'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector pause'*'--connector') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'connector-plugin search-jar'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--class --connector-plugin --connector-tag --help -c -h")" -- "$cur") ;; - *'container pause'*'--container') + *'debug java-debug'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug generate-diagnostics'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'debug block-traffic'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "start stop")" -- "$cur") ;; - *'connector create-or-update'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --initial-state --level --offsets --package --skip-automatic-connector-config --validate --verbose --wait-for-zero-lag -c -h -l -p -v")" -- "$cur") + *'schema set-normalize'*'--value') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "true false")" -- "$cur") ;; - *'connector log-level'*'--level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'container get-ip-addresses'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'topic consume'*'--key-subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'container get-properties'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'tcp-proxy close-connection'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'topic get-number-records'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'tools read-avro-file'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") + *'get-jmx-metrics'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic get-number-records'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'topic consume'*'--key-subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; *'debug log-level set'*'--level') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; - *'container get-ip-addresses'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'debug generate-diagnostics'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'get-jmx-metrics'*'--container') + *'debug heap-dump'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container get-properties'*'-c') + *'container pause'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'repro bootstrap'*'--pipeline') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro --sink-only "$cur")")" -- "$cur") + *'tools read-avro-file'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") ;; - *'container logs'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'tcp-proxy close-connection'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") ;; - *'container kill'*'--container') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector create-or-update'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --initial-state --level --offsets --package --skip-automatic-connector-config --validate --verbose --wait-for-zero-lag -c -h -l -p -v")" -- "$cur") ;; - *'debug block-traffic'*'--port') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") + *'connector log-level'*'--level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + ;; + + *'connector pause'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'config check-repo-version'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'container exec'*'--container') + *'container kill'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'repro bootstrap'*'--producer') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") + *'ec2 create'*'--instance-type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "c1.medium c1.xlarge c3.2xlarge c3.4xlarge c3.8xlarge c3.large c3.xlarge c4.2xlarge c4.4xlarge c4.large c4.xlarge m1.large m1.medium m1.small m1.xlarge m2.2xlarge m2.4xlarge m2.xlarge m3.2xlarge m3.large m3.medium m3.xlarge m4.10xlarge m4.2xlarge m4.4xlarge m4.large m4.xlarge t1.micro t2.large t2.medium t2.micro t2.nano t2.small t3.2xlarge")" -- "$cur") ;; - *'debug tcp-dump'*'--container') + *'container exec'*'--container') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector stop'*'--connector') + *'connector select-config'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector offsets alter'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container logs'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector select-config'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'repro bootstrap'*'--producer') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") ;; - *'tcp-proxy start'*'--hostname') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector stop'*'--connector') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'tcp-proxy get-connections'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + *'repro bootstrap'*'--pipeline') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro --sink-only "$cur")")" -- "$cur") ;; - *'connector offsets reset'*'-c') + *'connector offsets alter'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'ec2 create'*'--instance-type') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "c1.medium c1.xlarge c3.2xlarge c3.4xlarge c3.8xlarge c3.large c3.xlarge c4.2xlarge c4.4xlarge c4.large c4.xlarge m1.large m1.medium m1.small m1.xlarge m2.2xlarge m2.4xlarge m2.xlarge m3.2xlarge m3.large m3.medium m3.xlarge m4.10xlarge m4.2xlarge m4.4xlarge m4.large m4.xlarge t1.micro t2.large t2.medium t2.micro t2.nano t2.small t3.2xlarge")" -- "$cur") + *'debug block-traffic'*'--port') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") + ;; + + *'connector offsets reset'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'tools read-parquet-file'*'-f') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "parquet")")" -- "$cur") ;; - *'connector-plugin versions'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-plugin --force-refresh --help --last -c -h")" -- "$cur") + *'debug tcp-dump'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container ssh'*'--container') + *'tcp-proxy start'*'--hostname') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic get-number-records'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") + *'tcp-proxy get-connections'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --help -h")" -- "$cur") + ;; + + *'connector-plugin versions'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-plugin --force-refresh --help --last -c -h")" -- "$cur") + ;; + + *'container get-properties'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; *'run'*'--cluster-environment') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-environment-list "$cur")")" -- "$cur") ;; - *'config folder_zip_or_jar'*) + *'topic produce'*'--reference') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + ;; + + *'remove-all-docker-images'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'schema set-mode'*'--subject') + *'schema register'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'schema get-mode'*'--subject') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") + *'debug java-debug'*'--action') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "enable disable")" -- "$cur") ;; - *'container get-properties'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'schema get-compatibility'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; *'schema set-compatibility'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --help --subject --verbose -h -v")" -- "$cur") ;; - *'schema get-compatibility'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") + *'schema get-mode'*'--subject') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'remove-all-docker-images'*) + *'config folder_zip_or_jar'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'schema register'*'--subject') + *'schema set-mode'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'topic produce'*'--reference') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + *'container ssh'*'--container') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'debug java-debug'*'--action') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "enable disable")" -- "$cur") + *'topic get-number-records'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic -h -t")" -- "$cur") ;; - *'connector offsets alter'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'connector select-config'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") ;; *'connector show-config'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector offsets reset'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'cleanup-cloud-resources'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--force --help --resource -h")" -- "$cur") ;; *'connector offsets get'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'cleanup-cloud-resources'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--force --help --resource -h")" -- "$cur") - ;; - - *'connector select-config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") + *'connector offsets reset'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; *'tools read-parquet-file'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; + *'debug flight-recorder'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + *'schema register'*'--schema') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; - *'debug flight-recorder'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector offsets alter'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + ;; + + *'tools read-avro-file'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") ;; *'container change-jdk'*'-c') @@ -648,52 +660,44 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ssl_all ssl_handshake class_loading kerberos")" -- "$cur") ;; - *'tools read-avro-file'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-specific-file-extension "$cur" --extension "avro")")" -- "$cur") - ;; - - *'ec2 sync-repro-folder'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h ec2-to-local local-to-ec2")" -- "$cur") - ;; - - *'tcp-proxy start'*'--port') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") + *'connector offsets get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'repro bootstrap'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") + *'connector log-level'*'-l') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") ;; *'container exec'*'--shell') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'connector show-config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-rest-endpoint --help --verbose -c -h -v")" -- "$cur") + *'ec2 sync-repro-folder'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h ec2-to-local local-to-ec2")" -- "$cur") ;; *'connector log-level'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'schema set-mode'*'--mode') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") + *'tcp-proxy start'*'--port') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; - *'cleanup-cloud-details'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'topic describe'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector offsets get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'cleanup-cloud-details'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'topic describe'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'connector show-config'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --force-rest-endpoint --help --verbose -c -h -v")" -- "$cur") ;; - *'connector log-level'*'-l') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN DEBUG TRACE")" -- "$cur") + *'repro bootstrap'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") ;; *'debug log-level set'*'-l') @@ -708,11 +712,15 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic consume'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'schema set-mode'*'--mode') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "IMPORT READONLY READWRITE")" -- "$cur") ;; - *'topic produce'*'--topic') + *'connector show-lag'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'topic consume'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; @@ -720,6 +728,10 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; + *'topic produce'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + ;; + *'ec2 delete'*'--instance') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") ;; @@ -728,163 +740,155 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'connector show-lag'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") - ;; - *'schema derive-schema'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --payload --schema-type -h")" -- "$cur") ;; - *'debug tcp-dump'*'--port') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") - ;; - *'schema set-normalize'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --value --verbose -h -v")" -- "$cur") ;; - *'container ssh'*'--shell') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") + *'debug tcp-dump'*'--port') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-docker-ports)")" -- "$cur") ;; *'container change-jdk'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --version -c -h")" -- "$cur") ;; - *'debug log-level set'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --level --package -h -l -p")" -- "$cur") - ;; - - *'connector restart'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container ssh'*'--shell') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") ;; - *'debug log-level get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --package -h -p")" -- "$cur") + *'debug thread-dump'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'connector open-docs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") + *'topic delete'*'--topic') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'schema get'*'--subject') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-subject-list)")" -- "$cur") ;; - *'connector log-level'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level -c -h -l")" -- "$cur") - ;; - *'debug block-traffic'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --destination --help --port -c -h")" -- "$cur") ;; - *'debug thread-dump'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'debug log-level get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --package -h -p")" -- "$cur") ;; - *'topic delete'*'--topic') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") + *'debug log-level set'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --level --package -h -l -p")" -- "$cur") + ;; + + *'connector restart'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + ;; + + *'connector unpause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'update-version'*'--tag') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") ;; - *'container restart'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector open-docs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") ;; *'ec2 start'*'--instance') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'run'*'--cluster-region') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-kafka-region-list "$cur")")" -- "$cur") - ;; - - *'connector unpause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'container restart'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'container unpause'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'run'*'--cluster-region') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-kafka-region-list "$cur")")" -- "$cur") + ;; + + *'connector log-level'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --level -c -h -l")" -- "$cur") + ;; + *'topic alter'*'--topic') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'connector resume'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'tools certs-create'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --output-folder --verbose -h -v")" -- "$cur") ;; *'ec2 stop'*'--instance') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'connector versions'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'ec2 open'*'--instance') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + ;; + + *'connector status'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'container resume'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic produce'*'--key') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") + *'connector update'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'connector snippets'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--converter --dlq --help -h")" -- "$cur") ;; - *'debug java-debug'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") - ;; - - *'get-docker-compose'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'run'*'--connector-zip') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type zip "$cur")")" -- "$cur") ;; - *'connector status'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'debug java-debug'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container kill-all'*) + *'connector versions'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'repro import'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") + *'run'*'--connector-jar') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") ;; - *'container recreate'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --ignore-current-versions -h")" -- "$cur") + *'connector show-lag'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --interval --max-wait --verbose -c -h -v")" -- "$cur") ;; *'connector delete'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'run'*'--connector-jar') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-zip-or-jar-with-fzf --type jar "$cur")")" -- "$cur") + *'repro import'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") ;; - *'tools certs-create'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --output-folder --verbose -h -v")" -- "$cur") + *'container kill-all'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector show-lag'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --interval --max-wait --verbose -c -h -v")" -- "$cur") + *'container recreate'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --ignore-current-versions -h")" -- "$cur") ;; - *'connector update'*'-c') + *'connector resume'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; @@ -892,162 +896,146 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "aws gcp azure")" -- "$cur") ;; - *'ec2 open'*'--instance') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'get-docker-compose'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'run'*'--cluster-type') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "basic standard dedicated")" -- "$cur") + *'topic produce'*'--key') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-predefined-schemas "$cur")")" -- "$cur") ;; *'run'*'--cluster-name') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ccloud-cluster-list "$cur")")" -- "$cur") ;; - *'debug thread-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") - ;; - - *'connector offsets'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter get get-offsets-request-status reset")" -- "$cur") - ;; - *'connector plugins'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help --verbose -h -v")" -- "$cur") ;; - *'container restart'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'repro bootstrap'*'-p') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") ;; - *'debug heap-dump'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'repro bootstrap'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") ;; - *'connector pause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") + *'run'*'--cluster-type') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "basic standard dedicated")" -- "$cur") ;; - *'container pause'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector offsets'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter get get-offsets-request-status reset")" -- "$cur") ;; *'connector unpause'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'container unpause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'connector pause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; *'connector restart'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'repro bootstrap'*'-p') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "none avro avro-with-key protobuf protobuf-with-key json-schema json-schema-with-key")" -- "$cur") + *'debug thread-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + ;; + + *'container pause'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'get-jmx-metrics'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'repro bootstrap'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf --without-repro "$cur")")" -- "$cur") + *'container unpause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'container exec'*'-c') + *'debug heap-dump'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'container resume'*) + *'container restart'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'container kill'*'-c') + *'container logs'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'run'*'--environment') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") - ;; - - *'connector resume'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'topic describe'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'connector delete'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'container logs'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector resume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; *'connector stop'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-connector-list)")" -- "$cur") ;; - *'connector status'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") - ;; - - *'topic describe'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") - ;; - *'debug java-debug'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--action --container --help --type -c -h")" -- "$cur") ;; - *'config clipboard'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'container exec'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; *'debug tcp-dump'*'-c') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; + *'container kill'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + ;; + + *'container resume'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + ;; + *'connector-plugin'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h search-jar versions")" -- "$cur") ;; - *'connector update'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") + *'config clipboard'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'connector pause'*) + *'connector status'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'container ssh'*'-s') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") - ;; - - *'container pause'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'run'*'--environment') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "ccloud plaintext sasl-ssl sasl-plain 2way-ssl sasl-scram kraft-external-plaintext kraft-plaintext kerberos ssl_kerberos ldap-authorizer-sasl-plain ldap-sasl-plain rbac-sasl-plain")" -- "$cur") ;; - *'container ssh'*'-c') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") + *'connector update'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help -c -h")" -- "$cur") ;; - *'schema set-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") + *'container pause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; - *'schema get-mode'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") + *'debug heap-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") ;; *'tcp-proxy start'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --delay-service-response --help --hostname --port --service-response-corrupt --skip-automatic-connector-config --throttle-service-response -h")" -- "$cur") ;; - *'schema register'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --metadata-property --schema --subject --verbose -h -v")" -- "$cur") - ;; - *'topic consume'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; @@ -1056,58 +1044,66 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--custom-smt --description --file --help --pipeline -d -f -h")" -- "$cur") ;; - *'topic produce'*'-t') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") - ;; - *'get-jmx-metrics'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --domain --help --open -c -d -h -o")" -- "$cur") ;; + *'container ssh'*'-s') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "bash sh ksh zsh")" -- "$cur") + ;; + *'debug log-level'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h get set")" -- "$cur") ;; - *'debug heap-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --histo --live -c -h")" -- "$cur") + *'topic produce'*'-t') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; *'tcp-proxy delay'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connection-id --delay-service-response --help -h")" -- "$cur") ;; - *'tcp-proxy break'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") + *'schema set-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --mode --subject --verbose -h -v")" -- "$cur") ;; - *'container logs'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") + *'connector pause'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'debug tcp-dump'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --duration --help --port -c -h")" -- "$cur") + *'schema get-mode'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --subject --verbose -h -v")" -- "$cur") ;; - *'container exec'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--command --container --help --root --shell -c -h")" -- "$cur") + *'tcp-proxy break'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--break-service-response --connection-id --help -h")" -- "$cur") ;; - *'container kill'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") + *'container ssh'*'-c') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(docker ps --format '{{.Names}}')")" -- "$cur") ;; - *'topic describe'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") + *'schema register'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --metadata-property --schema --subject --verbose -h -v")" -- "$cur") ;; - *'connector stop'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") + *'container logs'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --max-wait --open --wait-for-log -c -h -m -o -w")" -- "$cur") ;; *'repro import'*'-f') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-playground-repro-export-with-fzf "$cur")")" -- "$cur") ;; + *'topic describe'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") + ;; + + *'update-version'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-jar --connector-tag --connector-zip --help --tag -h")" -- "$cur") + ;; + *'connector logs'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --lcc-id --max-wait --open --wait-for-log -h -m -o -w")" -- "$cur") ;; @@ -1116,39 +1112,55 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'update-version'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector-jar --connector-tag --connector-zip --help --tag -h")" -- "$cur") + *'connector stop'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--connector --help --verbose -c -h -v")" -- "$cur") ;; - *'schema delete'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --permanent --subject --verbose --version -h -v")" -- "$cur") + *'container exec'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--command --container --help --root --shell -c -h")" -- "$cur") + ;; + + *'debug tcp-dump'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --duration --help --port -c -h")" -- "$cur") + ;; + + *'container kill'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help -c -h")" -- "$cur") ;; *'get-ci-result'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'switch-ccloud'*) + *'config editor'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'--output-level') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") + *'switch-ccloud'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'debug testssl'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'container ssh'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") ;; *'topic alter'*'-t') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-topic-list)")" -- "$cur") ;; - *'container ssh'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--container --help --shell -c -h -s")" -- "$cur") + *'--output-level') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "INFO WARN ERROR")" -- "$cur") ;; - *'config editor'*) + *'schema delete'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --id --permanent --subject --verbose --version -h -v")" -- "$cur") + ;; + + *'topic produce'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --derive-key-schema-as --derive-value-schema-as --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --max-nb-messages-to-generate --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") + ;; + + *'debug testssl'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -1156,18 +1168,10 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--grep --help --key-subject --max-characters --max-messages --min-expected-messages --plot-latencies-timestamp-field --tail --timeout --topic --value-subject --verbose -h -t -v")" -- "$cur") ;; - *'topic produce'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--compatibility --compression-codec --consume --delete-topic --forced-key --forced-value --generate-only --headers --help --key --key-subject-name-strategy --max-nb-messages-per-batch --max-nb-messages-to-generate --nb-messages --nb-partitions --no-null --producer-property --record-size --sleep-time-between-batch --tombstone --topic --validate --validate-config --value --value-subject-name-strategy --verbose -h -t -v")" -- "$cur") - ;; - *'ec2 delete'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-cloudformation-list $cur)")" -- "$cur") ;; - *'repro export'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help -h")" -- "$cur") - ;; - *'topic delete'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --skip-delete-schema --topic --verbose -h -t -v")" -- "$cur") ;; @@ -1180,28 +1184,24 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; - *'switch-back'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'repro export'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--all --help -h")" -- "$cur") ;; *'topic alter'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --topic --verbose -h -t -v")" -- "$cur") ;; - *'ec2 start'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'switch-back'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'ec2 open'*'-i') + *'ec2 start'*'-i') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'schema get'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") - ;; - - *'topic list'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + *'open'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") ;; *'ec2 delete'*) @@ -1212,46 +1212,50 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance-type --size --suffix -h")" -- "$cur") ;; - *'open'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") + *'ec2 open'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'ec2 stop'*'-i') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") + *'topic list'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'run'*'--file') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") + *'schema get'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--deleted --help --id --subject --verbose -h -v")" -- "$cur") ;; - *'ec2 start'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + *'ec2 stop'*'-i') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-ec2-instance-list $cur)")" -- "$cur") ;; - *'connector'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create-or-update delete log-level logs offsets open-ccloud-connector-in-browser open-docs pause plugins restart resume select-config show-config show-config-parameters show-lag snippets status stop unpause update versions")" -- "$cur") + *'tcp-proxy'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h break close-all-connection-with-error close-connection delay get-connections start toggle-accept-connections toggle-reads-client toggle-reads-service toggle-writes-client toggle-writes-service")" -- "$cur") + ;; + + *'run'*'--file') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") ;; *'open-docs'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --only-show-url -h")" -- "$cur") ;; + *'ec2 start'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") + ;; + *'container'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h change-jdk exec get-ip-addresses get-properties kill kill-all logs pause recreate restart resume set-environment-variables ssh unpause")" -- "$cur") ;; - *'tcp-proxy'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h break close-all-connection-with-error close-connection delay get-connections start toggle-accept-connections toggle-reads-client toggle-reads-service toggle-writes-client toggle-writes-service")" -- "$cur") + *'connector'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h create-or-update delete log-level logs offsets open-ccloud-connector-in-browser open-docs pause plugins restart resume select-config show-config show-config-parameters show-lag snippets status stop unpause update versions")" -- "$cur") ;; *'run'*'--tag') while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-tag-list "$cur")")" -- "$cur") ;; - *'ec2 open'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--disable-sync-repro-folder --help --instance -h -i")" -- "$cur") - ;; - *'ec2 list'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; @@ -1260,36 +1264,32 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help --instance -h -i")" -- "$cur") ;; + *'ec2 open'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--disable-sync-repro-folder --help --instance -h -i")" -- "$cur") + ;; + *'history'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'open'*'-f') - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") + *'config'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h check-repo-version clipboard container-kill-all-before-run editor folder_zip_or_jar open-ccloud-connector-in-browser")" -- "$cur") ;; *'status'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'re-run'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - - *'config'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h check-repo-version clipboard container-kill-all-before-run editor folder_zip_or_jar open-ccloud-connector-in-browser")" -- "$cur") - ;; - *'schema'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h delete derive-schema get get-compatibility get-mode register set-compatibility set-mode set-normalize")" -- "$cur") ;; - *'topic'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter consume create delete describe display-consumer-offsets get-number-records list produce set-schema-compatibility")" -- "$cur") + *'re-run'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'debug'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h block-traffic enable-remote-debugging flight-recorder generate-diagnostics heap-dump java-debug log-level tcp-dump testssl thread-dump")" -- "$cur") + *'open'*'-f') + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-any-file-with-fzf "$cur")")" -- "$cur") ;; *'tools'*) @@ -1300,6 +1300,14 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "$(playground get-examples-list-with-fzf "$cur")")" -- "$cur") ;; + *'debug'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h block-traffic enable-remote-debugging flight-recorder generate-diagnostics heap-dump java-debug log-level tcp-dump testssl thread-dump")" -- "$cur") + ;; + + *'topic'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h alter consume create delete describe display-consumer-offsets get-number-records list produce set-schema-compatibility")" -- "$cur") + ;; + *'repro'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h bootstrap export import")" -- "$cur") ;; @@ -1308,14 +1316,14 @@ _playground_completions() { while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") ;; - *'stop'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") - ;; - *'open'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--file --help -f -h")" -- "$cur") ;; + *'stop'*) + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--help -h")" -- "$cur") + ;; + *'run'*) while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--cluster-cloud --cluster-creds --cluster-environment --cluster-name --cluster-region --cluster-schema-registry-creds --cluster-type --connector-jar --connector-tag --connector-zip --enable-conduktor --enable-control-center --enable-flink --enable-jmx-grafana --enable-kcat --enable-ksqldb --enable-multiple-brokers --enable-multiple-connect-workers --enable-rest-proxy --enable-sql-datagen --environment --file --help --open --tag -f -h -o")" -- "$cur") ;; diff --git a/scripts/cli/playground b/scripts/cli/playground index 2bc2d969a9..21d12f6469 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -70,7 +70,7 @@ playground_usage() { printf " %s 🔏 Set subject-level mode\n" "$(green "schema set-mode") " printf " %s 🧽 Set normalize at schema registry level\n" "$(green "schema set-normalize") " printf " %s 🧟 Delete schema\n" "$(green "schema delete") " - printf " %s 🔮 Derive a schema based on payload. \n" "$(green "schema derive-schema") " + printf " %s 🪄 Derive a schema based on payload\n" "$(green "schema derive-schema") " echo printf "%s\n" "$(bold "TCP Proxy commands:")" printf " %s 🏚 Zazkia TCP Proxy commands\n" "$(green "tcp-proxy") " @@ -2315,7 +2315,7 @@ playground_schema_usage() { printf " %s 🔏 Set subject-level mode\n" "$(green "set-mode") " printf " %s 🧽 Set normalize at schema registry level\n" "$(green "set-normalize") " printf " %s 🧟 Delete schema\n" "$(green "delete") " - printf " %s 🔮 Derive a schema based on payload. \n" "$(green "derive-schema") " + printf " %s 🪄 Derive a schema based on payload\n" "$(green "derive-schema") " echo # :command.long_usage @@ -2669,7 +2669,7 @@ playground_schema_delete_usage() { # :command.usage playground_schema_derive_schema_usage() { - printf "playground schema derive-schema - 🔮 Derive a schema based on payload. \n\n" + printf "playground schema derive-schema - 🪄 Derive a schema based on payload\n\n" printf "%s\n" "$(bold "== Usage ==")" printf " playground schema derive-schema [OPTIONS]\n" @@ -4760,6 +4760,18 @@ playground_topic_produce_usage() { printf " ☑️ Validate schema according to connect sink converter used\n" echo + # :flag.usage + printf " %s\n" "$(magenta "--derive-key-schema-as DERIVE-KEY-SCHEMA-AS")" + printf " 🪄 Use playground schema derive-schema command to deduce schema from key\n payload\n \n Possible values:\n \n - AVRO\n - JSON (json schema)\n - PROTOBUF\n" + printf " %s\n" "Allowed: AVRO, JSON, PROTOBUF" + echo + + # :flag.usage + printf " %s\n" "$(magenta "--derive-value-schema-as DERIVE-VALUE-SCHEMA-AS")" + printf " 🪄 Use playground schema derive-schema command to deduce schema from value\n payload\n \n Possible values:\n \n - AVRO\n - JSON (json schema)\n - PROTOBUF\n" + printf " %s\n" "Allowed: AVRO, JSON, PROTOBUF" + echo + # :flag.usage printf " %s\n" "$(magenta "--no-null")" printf " 🪹 Never generate null fields even for optional fields\n \n N.B: only work with avro and json-schema\n" @@ -18732,7 +18744,7 @@ EOF fi set -e - log "🔮 Schema file generated at $tmp_dir/schema_file" + log "🪄 Schema file generated" cat $tmp_dir/schema_file | jq -r '.schemas[]|del(.messagesMatched)|.schema' } @@ -20876,6 +20888,8 @@ playground_topic_produce_command() { no_null="${args[--no-null]}" consume="${args[--consume]}" delete_topic="${args[--delete-topic]}" + derive_key_schema_as="${args[--derive-key-schema-as]}" + derive_value_schema_as="${args[--derive-value-schema-as]}" # Convert the space delimited string to an array eval "validate_config=(${args[--validate-config]})" @@ -21143,12 +21157,46 @@ playground_topic_produce_command() { echo "$key" > "$key_schema_file" fi + if [[ -n "$derive_key_schema_as" ]] + then + log "🪄 --derive-key-schema-as $derive_key_schema_as is used" + set +e + output=$(playground --output-level ERROR schema derive-schema --schema-type "${derive_key_schema_as}" < "$key_schema_file") + if [ $? -ne 0 ] + then + logerror "❌ schema derivation failed" + echo "$output" + exit 1 + else + log "🪄 generated $derive_key_schema_as schema:" + echo "$output" + fi + set -e + echo "$output" > $key_schema_file + fi identify_schema "$key_schema_file" "key" key_schema_type=$schema_type fi if [[ ! -n "$tombstone" ]] then + if [[ -n "$derive_value_schema_as" ]] + then + log "🪄 --derive-value-schema-as $derive_value_schema_as is used" + set +e + output=$(playground --output-level ERROR schema derive-schema --schema-type "${derive_value_schema_as}" < "$value_schema_file") + if [ $? -ne 0 ] + then + logerror "❌ schema derivation failed" + echo "$output" + exit 1 + else + log "🪄 generated $derive_value_schema_as schema:" + echo "$output" + fi + set -e + echo "$output" > $value_schema_file + fi identify_schema "$value_schema_file" "value" value_schema_type=$schema_type fi @@ -31655,13 +31703,6 @@ playground_schema_derive_schema_parse_requirements() { exit 1 fi - # :command.user_filter - filter_error=$(filter_not_mdc_environment) - if [[ -n $filter_error ]]; then - echo "$filter_error" >&2 - exit 1 - fi - } # :command.parse_requirements @@ -36350,6 +36391,34 @@ playground_topic_produce_parse_requirements() { shift ;; + # :flag.case + --derive-key-schema-as) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + args['--derive-key-schema-as']="$2" + shift + shift + else + printf "%s\n" "--derive-key-schema-as requires an argument: --derive-key-schema-as DERIVE-KEY-SCHEMA-AS" >&2 + exit 1 + fi + ;; + + # :flag.case + --derive-value-schema-as) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + args['--derive-value-schema-as']="$2" + shift + shift + else + printf "%s\n" "--derive-value-schema-as requires an argument: --derive-value-schema-as DERIVE-VALUE-SCHEMA-AS" >&2 + exit 1 + fi + ;; + # :flag.case --no-null) @@ -36549,6 +36618,14 @@ playground_topic_produce_parse_requirements() { printf "%s\n" "--value-subject-name-strategy must be one of: TopicNameStrategy, RecordNameStrategy, TopicRecordNameStrategy" >&2 exit 1 fi + if [[ ${args['--derive-key-schema-as']:-} ]] && [[ ! ${args['--derive-key-schema-as']:-} =~ ^(AVRO|JSON|PROTOBUF)$ ]]; then + printf "%s\n" "--derive-key-schema-as must be one of: AVRO, JSON, PROTOBUF" >&2 + exit 1 + fi + if [[ ${args['--derive-value-schema-as']:-} ]] && [[ ! ${args['--derive-value-schema-as']:-} =~ ^(AVRO|JSON|PROTOBUF)$ ]]; then + printf "%s\n" "--derive-value-schema-as must be one of: AVRO, JSON, PROTOBUF" >&2 + exit 1 + fi input_array='' eval "input_array=(${args[--validate-config]})" for i in "${input_array[@]}"; do diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index 409a37d4ad..20297d02a9 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -828,7 +828,7 @@ }, { "name": "derive-schema", - "description": "🔮 Derive a schema based on payload. \n", + "description": "🪄 Derive a schema based on payload\n", "usage": "playground schema derive-schema [OPTIONS]", "options": [ { @@ -2064,6 +2064,28 @@ "argument": "", "description": "☑️ Validate schema according to connect sink converter used\n" }, + { + "names": [ + "--derive-key-schema-as" + ], + "argument": [ + "AVRO", + "JSON", + "PROTOBUF" + ], + "description": "🪄 Use playground schema derive-schema command to deduce schema from key payload\n\nPossible values:\n\n- AVRO\n- JSON (json schema)\n- PROTOBUF\n\nAllowed values: AVRO, JSON, PROTOBUF\n" + }, + { + "names": [ + "--derive-value-schema-as" + ], + "argument": [ + "AVRO", + "JSON", + "PROTOBUF" + ], + "description": "🪄 Use playground schema derive-schema command to deduce schema from value payload\n\nPossible values:\n\n- AVRO\n- JSON (json schema)\n- PROTOBUF\n\nAllowed values: AVRO, JSON, PROTOBUF\n" + }, { "names": [ "--no-null" diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index 63b17967f4..099e3b1464 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -959,7 +959,7 @@ subcommands: - name: derive-schema description: | - 🔮 Derive a schema based on payload. + 🪄 Derive a schema based on payload usage: playground schema derive-schema [OPTIONS] options: - names: @@ -2232,6 +2232,34 @@ subcommands: description: | ☑️ Validate schema according to connect sink converter used + - names: + - --derive-key-schema-as + argument: [AVRO, JSON, PROTOBUF] + description: | + 🪄 Use playground schema derive-schema command to deduce schema from key payload + + Possible values: + + - AVRO + - JSON (json schema) + - PROTOBUF + + Allowed values: AVRO, JSON, PROTOBUF + + - names: + - --derive-value-schema-as + argument: [AVRO, JSON, PROTOBUF] + description: | + 🪄 Use playground schema derive-schema command to deduce schema from value payload + + Possible values: + + - AVRO + - JSON (json schema) + - PROTOBUF + + Allowed values: AVRO, JSON, PROTOBUF + - names: - --no-null argument: "" diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index 0bfb26532b..f10d20ac8e 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -1397,10 +1397,8 @@ commands: - name: derive-schema group: Schema - filters: - - not_mdc_environment help: |- - 🔮 Derive a schema based on payload. + 🪄 Derive a schema based on payload flags: - long: --payload arg: payload @@ -1413,13 +1411,13 @@ commands: default: "AVRO" arg: schema-type help: |- - 🧩 Schema Registry schema "type": + 🧩 Schema Registry schema "type": - - AVRO - - JSON (json schema) - - PROTOBUF + - AVRO + - JSON (json schema) + - PROTOBUF - Default is AVRO + Default is AVRO allowed: - AVRO - JSON @@ -2515,6 +2513,38 @@ commands: help: |- ☑️ Validate schema according to connect sink converter used + - long: --derive-key-schema-as + required: false + arg: derive-key-schema-as + help: |- + 🪄 Use playground schema derive-schema command to deduce schema from key payload + + Possible values: + + - AVRO + - JSON (json schema) + - PROTOBUF + allowed: + - AVRO + - JSON + - PROTOBUF + + - long: --derive-value-schema-as + required: false + arg: derive-value-schema-as + help: |- + 🪄 Use playground schema derive-schema command to deduce schema from value payload + + Possible values: + + - AVRO + - JSON (json schema) + - PROTOBUF + allowed: + - AVRO + - JSON + - PROTOBUF + - long: --no-null required: false help: |- diff --git a/scripts/cli/src/commands/schema/derive-schema.sh b/scripts/cli/src/commands/schema/derive-schema.sh index 84fa369661..caf9fb7288 100644 --- a/scripts/cli/src/commands/schema/derive-schema.sh +++ b/scripts/cli/src/commands/schema/derive-schema.sh @@ -86,5 +86,5 @@ then fi set -e -log "🔮 Schema file generated at $tmp_dir/schema_file" +log "🪄 Schema file generated" cat $tmp_dir/schema_file | jq -r '.schemas[]|del(.messagesMatched)|.schema' \ No newline at end of file diff --git a/scripts/cli/src/commands/topic/produce.sh b/scripts/cli/src/commands/topic/produce.sh index c957173c8a..8b8997e738 100644 --- a/scripts/cli/src/commands/topic/produce.sh +++ b/scripts/cli/src/commands/topic/produce.sh @@ -23,6 +23,8 @@ value_schema_id="${args[--value-schema-id]}" no_null="${args[--no-null]}" consume="${args[--consume]}" delete_topic="${args[--delete-topic]}" +derive_key_schema_as="${args[--derive-key-schema-as]}" +derive_value_schema_as="${args[--derive-value-schema-as]}" # Convert the space delimited string to an array eval "validate_config=(${args[--validate-config]})" @@ -290,12 +292,46 @@ then echo "$key" > "$key_schema_file" fi + if [[ -n "$derive_key_schema_as" ]] + then + log "🪄 --derive-key-schema-as $derive_key_schema_as is used" + set +e + output=$(playground --output-level ERROR schema derive-schema --schema-type "${derive_key_schema_as}" < "$key_schema_file") + if [ $? -ne 0 ] + then + logerror "❌ schema derivation failed" + echo "$output" + exit 1 + else + log "🪄 generated $derive_key_schema_as schema:" + echo "$output" + fi + set -e + echo "$output" > $key_schema_file + fi identify_schema "$key_schema_file" "key" key_schema_type=$schema_type fi if [[ ! -n "$tombstone" ]] then + if [[ -n "$derive_value_schema_as" ]] + then + log "🪄 --derive-value-schema-as $derive_value_schema_as is used" + set +e + output=$(playground --output-level ERROR schema derive-schema --schema-type "${derive_value_schema_as}" < "$value_schema_file") + if [ $? -ne 0 ] + then + logerror "❌ schema derivation failed" + echo "$output" + exit 1 + else + log "🪄 generated $derive_value_schema_as schema:" + echo "$output" + fi + set -e + echo "$output" > $value_schema_file + fi identify_schema "$value_schema_file" "value" value_schema_type=$schema_type fi From abcc877c264b8ed3edc819b610a47ecd74414698 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 11 Feb 2025 15:50:17 +0100 Subject: [PATCH 232/659] use playground connector create-or-update --- .../lenses-active-mq-source.json | 7 ------- .../lenses-active-mq-source.sh | 13 +++++++++---- 2 files changed, 9 insertions(+), 11 deletions(-) delete mode 100644 connect/connect-lenses-active-mq-source/lenses-active-mq-source.json diff --git a/connect/connect-lenses-active-mq-source/lenses-active-mq-source.json b/connect/connect-lenses-active-mq-source/lenses-active-mq-source.json deleted file mode 100644 index abf164fe91..0000000000 --- a/connect/connect-lenses-active-mq-source/lenses-active-mq-source.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "connector.class": "com.datamountaineer.streamreactor.connect.jms.source.JMSSourceConnector", - "connect.jms.kcql": "INSERT INTO MyKafkaTopicName SELECT * FROM myqueue WITHTYPE QUEUE WITHCONVERTER=`com.datamountaineer.streamreactor.connect.converters.source.JsonSimpleConverter`", - "connect.jms.url": "tcp://activemq:61616", - "connect.jms.initial.context.factory": "org.apache.activemq.jndi.ActiveMQInitialContextFactory", - "connect.jms.connection.factory": "ConnectionFactory" -} \ No newline at end of file diff --git a/connect/connect-lenses-active-mq-source/lenses-active-mq-source.sh b/connect/connect-lenses-active-mq-source/lenses-active-mq-source.sh index 8204b8ef7e..391e883156 100755 --- a/connect/connect-lenses-active-mq-source/lenses-active-mq-source.sh +++ b/connect/connect-lenses-active-mq-source/lenses-active-mq-source.sh @@ -29,10 +29,15 @@ playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker- log "Creating Lenses JMS ActiveMQ source connector" -curl -X PUT \ - -H "Content-Type: application/json" \ - --data @lenses-active-mq-source.json \ - http://localhost:8083/connectors/lenses-active-mq-source/config | jq . +playground connector create-or-update --connector lenses-active-mq-source << EOF +{ + "connector.class": "com.datamountaineer.streamreactor.connect.jms.source.JMSSourceConnector", + "connect.jms.kcql": "INSERT INTO MyKafkaTopicName SELECT * FROM myqueue WITHTYPE QUEUE WITHCONVERTER=\`com.datamountaineer.streamreactor.connect.converters.source.JsonSimpleConverter\`", + "connect.jms.url": "tcp://activemq:61616", + "connect.jms.initial.context.factory": "org.apache.activemq.jndi.ActiveMQInitialContextFactory", + "connect.jms.connection.factory": "ConnectionFactory" +} +EOF sleep 5 From 79d94fbe718aa6bc2c9ce1b4170e0908fe216be2 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 11 Feb 2025 15:50:31 +0100 Subject: [PATCH 233/659] cosmetic --- ccloud/environment/start.sh | 4 ++-- .../cdc-oracle12-cdb-table-mtls-db-auth.sh | 2 +- .../cdc-oracle12-cdb-table-mtls.sh | 2 +- .../connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh | 2 +- .../cdc-oracle12-pdb-table-mtls-db-auth.sh | 2 +- .../cdc-oracle12-pdb-table-mtls.sh | 2 +- .../connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh | 2 +- .../cdc-oracle18-cdb-table-mtls-db-auth.sh | 2 +- .../cdc-oracle18-cdb-table-mtls.sh | 2 +- .../connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh | 2 +- .../cdc-oracle18-pdb-table-mtls.sh | 2 +- .../connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh | 2 +- .../cdc-oracle19-cdb-table-mtls-db-auth.sh | 2 +- .../cdc-oracle19-cdb-table-mtls.sh | 2 +- .../connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh | 2 +- .../cdc-oracle19-pdb-table-mtls-db-auth.sh | 2 +- .../cdc-oracle19-pdb-table-mtls.sh | 2 +- .../connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh | 2 +- .../cdc-oracle21-cdb-table-mtls-db-auth.sh | 2 +- .../cdc-oracle21-cdb-table-mtls.sh | 2 +- .../connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh | 2 +- .../cdc-oracle21-pdb-table-mtls-db-auth.sh | 2 +- .../cdc-oracle21-pdb-table-mtls.sh | 2 +- .../connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh | 2 +- connect/connect-jdbc-ibmdb2-sink/ibmdb2-sink-ssl.sh | 2 +- connect/connect-jdbc-ibmdb2-source/ibmdb2-source-ssl.sh | 2 +- connect/connect-jdbc-ibmdb2-source/ibmdb2-source.sh | 2 +- .../connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh | 2 +- connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh | 2 +- connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh | 2 +- connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh | 2 +- connect/connect-jdbc-oracle12-source/oracle12-mtls.sh | 2 +- connect/connect-jdbc-oracle12-source/oracle12-ssl.sh | 2 +- .../connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh | 2 +- connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh | 2 +- connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh | 2 +- connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh | 2 +- connect/connect-jdbc-oracle19-source/oracle19-mtls.sh | 2 +- connect/connect-jdbc-oracle19-source/oracle19-ssl.sh | 2 +- .../connect-jdbc-oracle21-sink/oracle21-sink-mtls-db-auth.sh | 2 +- connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls.sh | 2 +- connect/connect-jdbc-oracle21-sink/oracle21-sink-ssl.sh | 2 +- connect/connect-jdbc-oracle21-source/oracle21-mtls-db-auth.sh | 2 +- connect/connect-jdbc-oracle21-source/oracle21-mtls.sh | 2 +- connect/connect-jdbc-oracle21-source/oracle21-ssl.sh | 2 +- connect/connect-jms-oracle19-sink/jms-oracle19-sink.sh | 2 +- connect/connect-jms-oracle19-source/jms-oracle19-source.sh | 2 +- connect/connect-jms-oracle21-sink/jms-oracle21-sink.sh | 2 +- connect/connect-jms-oracle21-source/jms-oracle21-source.sh | 2 +- environment/2way-ssl/start.sh | 4 ++-- environment/kerberos/start.sh | 4 ++-- environment/kraft-external-plaintext/start.sh | 4 ++-- environment/kraft-plaintext/start.sh | 4 ++-- environment/ldap-authorizer-sasl-plain/start.sh | 4 ++-- environment/ldap-sasl-plain/start.sh | 4 ++-- environment/mdc-kerberos/start.sh | 4 ++-- environment/mdc-plaintext/start.sh | 4 ++-- environment/mdc-sasl-plain/start.sh | 4 ++-- environment/plaintext/start.sh | 4 ++-- environment/rbac-sasl-plain/start.sh | 4 ++-- environment/sasl-plain/start.sh | 4 ++-- environment/sasl-scram/start.sh | 4 ++-- environment/sasl-ssl/start.sh | 4 ++-- environment/ssl_kerberos/start.sh | 4 ++-- other/rbac-with-azure-ad/start.sh | 4 ++-- reproduction-models | 2 +- 66 files changed, 83 insertions(+), 83 deletions(-) diff --git a/ccloud/environment/start.sh b/ccloud/environment/start.sh index 193622cbcf..6b6d5d7bdb 100755 --- a/ccloud/environment/start.sh +++ b/ccloud/environment/start.sh @@ -49,11 +49,11 @@ fi docker compose -f ../../ccloud/environment/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} build docker compose -f ../../ccloud/environment/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} down -v --remove-orphans docker compose -f ../../ccloud/environment/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} ${profile_control_center_command} ${profile_conduktor_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../ccloud/environment/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_conduktor_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "ccloud" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls-db-auth.sh index 760d5fbc3a..c8d7768d5c 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls-db-auth.sh @@ -205,7 +205,7 @@ set_profiles command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.cdb-table-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh index 603408c94f..28ef91ce32 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh @@ -199,7 +199,7 @@ set_profiles command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.cdb-table-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh index c31ca0a8e4..5d3dfbb751 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh @@ -171,7 +171,7 @@ set_profiles command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.cdb-table-ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh index dd310fb6f2..8b336541b4 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh @@ -219,7 +219,7 @@ set_profiles command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.pdb-table-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh index c4f04bd977..d7ec507d64 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh @@ -211,7 +211,7 @@ set_profiles command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.pdb-table-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh index 870f077444..7616894413 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh @@ -183,7 +183,7 @@ set_profiles command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.pdb-table-ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls-db-auth.sh index 7b32960516..84b2268b7a 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls-db-auth.sh @@ -205,7 +205,7 @@ set_profiles command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.cdb-table-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh index 6b6db30896..bf79a99725 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh @@ -201,7 +201,7 @@ set_profiles command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.cdb-table-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh index 87b4be1eac..08e7c51ff9 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh @@ -171,7 +171,7 @@ set_profiles command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.cdb-table-ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh index 2c8d5e007c..d12b243132 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh @@ -211,7 +211,7 @@ set_profiles command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.pdb-table-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh index 508ed8d1ac..c6f7aa74ba 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh @@ -183,7 +183,7 @@ set_profiles command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.pdb-table-ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls-db-auth.sh index 200b1e432b..f999bafaaa 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls-db-auth.sh @@ -200,7 +200,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.cdb-table-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh index 78daf6d146..c646906c39 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh @@ -194,7 +194,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.cdb-table-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh index 7ae08f2c9a..4df13e9bdb 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh @@ -167,7 +167,7 @@ set_profiles command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.cdb-table-ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh index 63eeed487e..a6e131c73f 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh @@ -219,7 +219,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.pdb-table-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh index 7732622e13..52e06ef7a3 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh @@ -211,7 +211,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.pdb-table-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh index c8a57bc444..b3f43653bb 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh @@ -183,7 +183,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.pdb-table-ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh index fcc1667019..df36e23386 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh @@ -200,7 +200,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.cdb-table-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh index e4076a74a7..7f2972c2e3 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh @@ -194,7 +194,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.cdb-table-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh index 29417c851c..6a85ca63b9 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh @@ -166,7 +166,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.cdb-table-ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh index 150b067c67..9877a29ac4 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh @@ -219,7 +219,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.pdb-table-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh index bdac42a2fd..617190a73c 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh @@ -211,7 +211,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.pdb-table-mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh index 57cfe5fc8c..9b70353220 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh @@ -183,7 +183,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.pdb-table-ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-ibmdb2-sink/ibmdb2-sink-ssl.sh b/connect/connect-jdbc-ibmdb2-sink/ibmdb2-sink-ssl.sh index 82f379ed55..5e6a3ecc30 100755 --- a/connect/connect-jdbc-ibmdb2-sink/ibmdb2-sink-ssl.sh +++ b/connect/connect-jdbc-ibmdb2-sink/ibmdb2-sink-ssl.sh @@ -98,7 +98,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-ibmdb2-source/ibmdb2-source-ssl.sh b/connect/connect-jdbc-ibmdb2-source/ibmdb2-source-ssl.sh index 8c01295fa6..1e52cb82cd 100755 --- a/connect/connect-jdbc-ibmdb2-source/ibmdb2-source-ssl.sh +++ b/connect/connect-jdbc-ibmdb2-source/ibmdb2-source-ssl.sh @@ -98,7 +98,7 @@ set_profiles command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-ibmdb2-source/ibmdb2-source.sh b/connect/connect-jdbc-ibmdb2-source/ibmdb2-source.sh index 0390444263..1112b339f6 100755 --- a/connect/connect-jdbc-ibmdb2-source/ibmdb2-source.sh +++ b/connect/connect-jdbc-ibmdb2-source/ibmdb2-source.sh @@ -42,7 +42,7 @@ set_profiles command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.yml" ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh index de335312f0..c2844e44ea 100755 --- a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh @@ -141,7 +141,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh index 6cc7e825c2..18bcfad70c 100755 --- a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh +++ b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh @@ -137,7 +137,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready sleep 10 diff --git a/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh b/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh index e6bf213572..cdd1963da4 100755 --- a/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh +++ b/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh @@ -109,7 +109,7 @@ sleep 60 command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" - log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" + log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh b/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh index 602ed8b300..c8a636e86a 100755 --- a/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh @@ -176,7 +176,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh b/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh index 8434c4b541..844913b664 100755 --- a/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh +++ b/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh @@ -170,7 +170,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh b/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh index bb0c148f18..f9fd5f2123 100755 --- a/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh +++ b/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh @@ -142,7 +142,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh index b31887fcbf..db67df9a00 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh @@ -142,7 +142,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh index 0fac4e3aa7..c2ed892fd2 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh @@ -137,7 +137,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh index e9a44b7211..f9e413fb09 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh @@ -108,7 +108,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh b/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh index 3b8b3ed3b1..f32a0841b9 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh @@ -176,7 +176,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh b/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh index 785bf3b133..443016ac13 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh @@ -170,7 +170,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh b/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh index 3071228e1f..85b5bfc86e 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh @@ -142,7 +142,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls-db-auth.sh b/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls-db-auth.sh index ca58e65aa2..fb94721f31 100755 --- a/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls-db-auth.sh @@ -142,7 +142,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls.sh b/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls.sh index dd39618847..17fc3988be 100755 --- a/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls.sh +++ b/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls.sh @@ -136,7 +136,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle21-sink/oracle21-sink-ssl.sh b/connect/connect-jdbc-oracle21-sink/oracle21-sink-ssl.sh index bbd5c88b16..7c5bd6345b 100755 --- a/connect/connect-jdbc-oracle21-sink/oracle21-sink-ssl.sh +++ b/connect/connect-jdbc-oracle21-sink/oracle21-sink-ssl.sh @@ -108,7 +108,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle21-source/oracle21-mtls-db-auth.sh b/connect/connect-jdbc-oracle21-source/oracle21-mtls-db-auth.sh index ce6cab3406..0d74d5a6dc 100755 --- a/connect/connect-jdbc-oracle21-source/oracle21-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle21-source/oracle21-mtls-db-auth.sh @@ -176,7 +176,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls-db-auth.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle21-source/oracle21-mtls.sh b/connect/connect-jdbc-oracle21-source/oracle21-mtls.sh index 17bae21a11..3a469c9b10 100755 --- a/connect/connect-jdbc-oracle21-source/oracle21-mtls.sh +++ b/connect/connect-jdbc-oracle21-source/oracle21-mtls.sh @@ -170,7 +170,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.mtls.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jdbc-oracle21-source/oracle21-ssl.sh b/connect/connect-jdbc-oracle21-source/oracle21-ssl.sh index 0d21462698..95068df330 100755 --- a/connect/connect-jdbc-oracle21-source/oracle21-ssl.sh +++ b/connect/connect-jdbc-oracle21-source/oracle21-ssl.sh @@ -142,7 +142,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.ssl.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jms-oracle19-sink/jms-oracle19-sink.sh b/connect/connect-jms-oracle19-sink/jms-oracle19-sink.sh index 5f77a9f9da..a88be53762 100755 --- a/connect/connect-jms-oracle19-sink/jms-oracle19-sink.sh +++ b/connect/connect-jms-oracle19-sink/jms-oracle19-sink.sh @@ -55,7 +55,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jms-oracle19-source/jms-oracle19-source.sh b/connect/connect-jms-oracle19-source/jms-oracle19-source.sh index 82cb1ec450..e360118a8a 100755 --- a/connect/connect-jms-oracle19-source/jms-oracle19-source.sh +++ b/connect/connect-jms-oracle19-source/jms-oracle19-source.sh @@ -56,7 +56,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jms-oracle21-sink/jms-oracle21-sink.sh b/connect/connect-jms-oracle21-sink/jms-oracle21-sink.sh index f26edbfe72..7de648db14 100755 --- a/connect/connect-jms-oracle21-sink/jms-oracle21-sink.sh +++ b/connect/connect-jms-oracle21-sink/jms-oracle21-sink.sh @@ -55,7 +55,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/connect/connect-jms-oracle21-source/jms-oracle21-source.sh b/connect/connect-jms-oracle21-source/jms-oracle21-source.sh index 4c765049a7..a10be30eac 100755 --- a/connect/connect-jms-oracle21-source/jms-oracle21-source.sh +++ b/connect/connect-jms-oracle21-source/jms-oracle21-source.sh @@ -56,7 +56,7 @@ docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/dock command="source ${DIR}/../../scripts/utils.sh && docker compose -f ../../environment/plaintext/docker-compose.yml -f ${PWD}/docker-compose.plaintext.yml up -d ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/environment/2way-ssl/start.sh b/environment/2way-ssl/start.sh index 65d014ce34..d3640ea481 100755 --- a/environment/2way-ssl/start.sh +++ b/environment/2way-ssl/start.sh @@ -28,11 +28,11 @@ playground tools certs-create --output-folder "${PWD}/../../environment/2way-ssl docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/2way-ssl/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} build docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/2way-ssl/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} down -v --remove-orphans docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/2way-ssl/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml -f ${DIR}/../../environment/2way-ssl/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "2way-ssl" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" diff --git a/environment/kerberos/start.sh b/environment/kerberos/start.sh index 9803e2d1de..052bfb3bfe 100755 --- a/environment/kerberos/start.sh +++ b/environment/kerberos/start.sh @@ -126,11 +126,11 @@ fi # Starting zookeeper and kafka now that the keytab has been created with the required credentials and services docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/kerberos/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} build docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/kerberos/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml -f ${DIR}/../../environment/kerberos/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_kafka_nodes_command}${profile_connect_nodes_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "kerberos" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" diff --git a/environment/kraft-external-plaintext/start.sh b/environment/kraft-external-plaintext/start.sh index 2363213466..0b59e1b442 100755 --- a/environment/kraft-external-plaintext/start.sh +++ b/environment/kraft-external-plaintext/start.sh @@ -31,11 +31,11 @@ set_profiles docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/kraft-external-plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} build docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/kraft-external-plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} down -v --remove-orphans docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/kraft-external-plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_connect_nodes_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml -f ${DIR}/../../environment/kraft-plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_connect_nodes_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "kraft-external-plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" diff --git a/environment/kraft-plaintext/start.sh b/environment/kraft-plaintext/start.sh index fc2ce0fded..e0bf058b35 100755 --- a/environment/kraft-plaintext/start.sh +++ b/environment/kraft-plaintext/start.sh @@ -38,11 +38,11 @@ fi docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/kraft-plaintext/$KRAFT_DOCKER_COMPOSE ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} build docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/kraft-plaintext/$KRAFT_DOCKER_COMPOSE ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} down -v --remove-orphans docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/kraft-plaintext/$KRAFT_DOCKER_COMPOSE ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_connect_nodes_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml -f ${DIR}/../../environment/kraft-plaintext/$KRAFT_DOCKER_COMPOSE ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_connect_nodes_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "kraft-plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" diff --git a/environment/ldap-authorizer-sasl-plain/start.sh b/environment/ldap-authorizer-sasl-plain/start.sh index 9d4ebc8944..c008369d24 100755 --- a/environment/ldap-authorizer-sasl-plain/start.sh +++ b/environment/ldap-authorizer-sasl-plain/start.sh @@ -26,11 +26,11 @@ set_profiles docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/sasl-plain/docker-compose.yml -f ../../environment/ldap-authorizer-sasl-plain/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} build docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/sasl-plain/docker-compose.yml -f ../../environment/ldap-authorizer-sasl-plain/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} down -v --remove-orphans docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/sasl-plain/docker-compose.yml -f ../../environment/ldap-authorizer-sasl-plain/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml -f ${DIR}/../../environment/sasl-plain/docker-compose.yml -f ../../environment/ldap-authorizer-sasl-plain/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "ldap-authorizer-sasl-plain" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" diff --git a/environment/ldap-sasl-plain/start.sh b/environment/ldap-sasl-plain/start.sh index 56df5f5a70..ec113cf13e 100755 --- a/environment/ldap-sasl-plain/start.sh +++ b/environment/ldap-sasl-plain/start.sh @@ -31,11 +31,11 @@ set_profiles docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/sasl-plain/docker-compose.yml -f ../../environment/ldap-sasl-plain/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} build docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/sasl-plain/docker-compose.yml -f ../../environment/ldap-sasl-plain/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} down -v --remove-orphans docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/sasl-plain/docker-compose.yml -f ../../environment/ldap-sasl-plain/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml -f ${DIR}/../../environment/sasl-plain/docker-compose.yml -f ../../environment/ldap-sasl-plain/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "ldap-sasl-plain" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" diff --git a/environment/mdc-kerberos/start.sh b/environment/mdc-kerberos/start.sh index 995ab63094..fe26d9e1ca 100755 --- a/environment/mdc-kerberos/start.sh +++ b/environment/mdc-kerberos/start.sh @@ -109,11 +109,11 @@ fi docker compose -f ../../environment/mdc-plaintext/docker-compose.yml -f ../../environment/mdc-kerberos/docker-compose.kerberos.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} build docker compose -f ../../environment/mdc-plaintext/docker-compose.yml -f ../../environment/mdc-kerberos/docker-compose.kerberos.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} ${profile_control_center_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/mdc-plaintext/docker-compose.yml -f ${DIR}/../../environment/mdc-kerberos/docker-compose.kerberos.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} ${profile_control_center_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "mdc-kerberos" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" diff --git a/environment/mdc-plaintext/start.sh b/environment/mdc-plaintext/start.sh index 4373a2b951..519f934370 100755 --- a/environment/mdc-plaintext/start.sh +++ b/environment/mdc-plaintext/start.sh @@ -54,11 +54,11 @@ fi docker compose -f ../../environment/mdc-plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} build docker compose -f ../../environment/mdc-plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} down -v --remove-orphans docker compose -f ../../environment/mdc-plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} ${profile_control_center_command} ${profile_flink} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/mdc-plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} ${profile_control_center_command} ${profile_flink} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "mdc-plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" diff --git a/environment/mdc-sasl-plain/start.sh b/environment/mdc-sasl-plain/start.sh index 2030c927c6..8d2583bad2 100755 --- a/environment/mdc-sasl-plain/start.sh +++ b/environment/mdc-sasl-plain/start.sh @@ -41,11 +41,11 @@ fi docker compose -f ../../environment/mdc-plaintext/docker-compose.yml -f ../../environment/mdc-sasl-plain/docker-compose.sasl-plain.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} build docker compose -f ../../environment/mdc-plaintext/docker-compose.yml -f ../../environment/mdc-sasl-plain/docker-compose.sasl-plain.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} down -v --remove-orphans docker compose -f ../../environment/mdc-plaintext/docker-compose.yml -f ../../environment/mdc-sasl-plain/docker-compose.sasl-plain.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} ${profile_control_center_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/mdc-plaintext/docker-compose.yml -f ${DIR}/../../environment/mdc-sasl-plain/docker-compose.sasl-plain.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} ${profile_control_center_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "mdc-sasl-plain" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" diff --git a/environment/plaintext/start.sh b/environment/plaintext/start.sh index 02a84f433b..d648d31763 100755 --- a/environment/plaintext/start.sh +++ b/environment/plaintext/start.sh @@ -26,11 +26,11 @@ set_profiles docker compose -f ../../environment/plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} build docker compose -f ../../environment/plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} down -v --remove-orphans docker compose -f ../../environment/plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_flink} ${profile_ksqldb_command} ${profile_rest_proxy_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_sql_datagen_command} ${profile_connect_nodes_command} ${profile_kafka_nodes_command} ${profile_schema_registry_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_flink} ${profile_ksqldb_command} ${profile_rest_proxy_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_sql_datagen_command} ${profile_connect_nodes_command} ${profile_kafka_nodes_command} ${profile_schema_registry_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "plaintext" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/environment/rbac-sasl-plain/start.sh b/environment/rbac-sasl-plain/start.sh index 33f76b2acf..8e3a5dc02c 100755 --- a/environment/rbac-sasl-plain/start.sh +++ b/environment/rbac-sasl-plain/start.sh @@ -125,11 +125,11 @@ docker exec -i tools bash -c "/tmp/helper/validate_bindings.sh" docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/rbac-sasl-plain/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} build docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/rbac-sasl-plain/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml -f ${DIR}/../../environment/rbac-sasl-plain/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "rbac-sasl-plain" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/environment/sasl-plain/start.sh b/environment/sasl-plain/start.sh index 7d99dc5fdb..5f3d4c8628 100755 --- a/environment/sasl-plain/start.sh +++ b/environment/sasl-plain/start.sh @@ -27,11 +27,11 @@ set_profiles docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/sasl-plain/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} build docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/sasl-plain/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} down -v --remove-orphans docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/sasl-plain/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_conduktor_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml -f ${DIR}/../../environment/sasl-plain/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_conduktor_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "sasl-plain" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" diff --git a/environment/sasl-scram/start.sh b/environment/sasl-scram/start.sh index f5d661ca54..d662f15255 100755 --- a/environment/sasl-scram/start.sh +++ b/environment/sasl-scram/start.sh @@ -45,11 +45,11 @@ else fi docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/sasl-scram/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml -f ${DIR}/../../environment/sasl-scram/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "sasl-scram" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" diff --git a/environment/sasl-ssl/start.sh b/environment/sasl-ssl/start.sh index 70f30046d9..c5a1cb07f3 100755 --- a/environment/sasl-ssl/start.sh +++ b/environment/sasl-ssl/start.sh @@ -29,11 +29,11 @@ set_profiles docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/sasl-ssl/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} build docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/sasl-ssl/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} down -v --remove-orphans docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/sasl-ssl/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml -f ${DIR}/../../environment/sasl-ssl/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "sasl-ssl" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" diff --git a/environment/ssl_kerberos/start.sh b/environment/ssl_kerberos/start.sh index 30396b17d4..4604c61300 100755 --- a/environment/ssl_kerberos/start.sh +++ b/environment/ssl_kerberos/start.sh @@ -124,11 +124,11 @@ then fi # Starting zookeeper and kafka now that the keytab has been created with the required credentials and services docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/ssl_kerberos/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml -f ${DIR}/../../environment/ssl_kerberos/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} ${profile_conduktor_command} ${profile_kafka_nodes_command} ${profile_connect_nodes_command} up -d --quiet-pull" playground state set run.docker_command "$command" playground state set run.environment "ssl_kerberos" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" diff --git a/other/rbac-with-azure-ad/start.sh b/other/rbac-with-azure-ad/start.sh index bb2f812c80..da2b846698 100755 --- a/other/rbac-with-azure-ad/start.sh +++ b/other/rbac-with-azure-ad/start.sh @@ -74,11 +74,11 @@ docker exec -i tools bash -c "/tmp/helper/create-role-bindings.sh" docker compose -f ../../environment/plaintext/docker-compose.yml -f ../../environment/rbac-sasl-plain/docker-compose.yml -f "${PWD}/docker-compose.rbac-with-azure-ad.yml" ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d --quiet-pull -log "📝 To see the actual properties file, use cli command playground container get-properties -c " +log "📝 To see the actual properties file, use cli command 'playground container get-properties -c '" command="source ${DIR}/../../scripts/utils.sh && docker compose -f ${DIR}/../../environment/plaintext/docker-compose.yml -f ${DIR}/../../environment/rbac-sasl-plain/docker-compose.yml -f ${PWD}/docker-compose.rbac-with-azure-ad.yml ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d" playground state set run.docker_command "$command" playground state set run.environment "rbac-sasl-plain" -log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command playground container recreate" +log "✨ If you modify a docker-compose file and want to re-create the container(s), run cli command 'playground container recreate'" wait_container_ready diff --git a/reproduction-models b/reproduction-models index e5cddd1cfb..f684425a7f 160000 --- a/reproduction-models +++ b/reproduction-models @@ -1 +1 @@ -Subproject commit e5cddd1cfbddee7bf945fee59b4429d037364143 +Subproject commit f684425a7fd16de224be74db0f8e416692e8a17b From 2dbe22263d8118c05643f4a7e6cabd5cdc85d9b8 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 11 Feb 2025 16:56:30 +0100 Subject: [PATCH 234/659] add retries --- scripts/cli/playground | 12 +++++++++--- scripts/cli/src/lib/cli_function.sh | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 21d12f6469..7fe903f1c0 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -7237,9 +7237,15 @@ function filter_ccloud_environment() { function filter_schema_registry_running() { get_sr_url_and_security - curl $sr_security -s "${sr_url}/config" > /dev/null 2>&1 - if [ $? != 0 ] - then + for i in {1..30}; do + curl $sr_security -s "${sr_url}/config" > /dev/null 2>&1 + if [ $? == 0 ]; then + break + fi + sleep 1 + done + + if [ $? != 0 ]; then logerror "schema registry rest api should be running to run this command" fi } diff --git a/scripts/cli/src/lib/cli_function.sh b/scripts/cli/src/lib/cli_function.sh index a6fe6d1aec..225b9615f1 100644 --- a/scripts/cli/src/lib/cli_function.sh +++ b/scripts/cli/src/lib/cli_function.sh @@ -778,9 +778,15 @@ function filter_ccloud_environment() { function filter_schema_registry_running() { get_sr_url_and_security - curl $sr_security -s "${sr_url}/config" > /dev/null 2>&1 - if [ $? != 0 ] - then + for i in {1..30}; do + curl $sr_security -s "${sr_url}/config" > /dev/null 2>&1 + if [ $? == 0 ]; then + break + fi + sleep 1 + done + + if [ $? != 0 ]; then logerror "schema registry rest api should be running to run this command" fi } From d6d9ab784ff41f2c0748af7c09e9a5dc833f2b34 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 12 Feb 2025 10:35:57 +0100 Subject: [PATCH 235/659] remove check if continue --- scripts/cli/playground | 1 - scripts/cli/src/commands/get-ci-result.sh | 1 - 2 files changed, 2 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 7fe903f1c0..01b821c312 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -15516,7 +15516,6 @@ playground_get_ci_result_command() { if [ -n "$result_fail" ] then logwarn "$result_fail" - check_if_continue fi if [ -n "$result_not_tested" ] diff --git a/scripts/cli/src/commands/get-ci-result.sh b/scripts/cli/src/commands/get-ci-result.sh index cb0e5eb371..5566ab6842 100644 --- a/scripts/cli/src/commands/get-ci-result.sh +++ b/scripts/cli/src/commands/get-ci-result.sh @@ -40,7 +40,6 @@ fi if [ -n "$result_fail" ] then logwarn "$result_fail" - check_if_continue fi if [ -n "$result_not_tested" ] From 274624035e8abe34e97f53b7d6d3fa78d9773695 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 12 Feb 2025 13:11:50 +0100 Subject: [PATCH 236/659] workaround for issue with CP 7.8.1 --- scripts/cli/playground | 2 +- scripts/cli/src/commands/tools/certs-create.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 01b821c312..d3e920ef3d 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -19265,7 +19265,7 @@ playground_tools_certs_create_command() { cd "${output_folder}" cp $root_folder/scripts/cli/src/ssl/certs-create.sh . log "🔐 Generate keys and certificates in folder ${output_folder}" - docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" + docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "ln -s /usr/local/lib64/libssl.so.3 /usr/lib64/libssl.so.3;ln -s /usr/local/lib64/libcrypto.so.3 /usr/lib64/libcrypto.so.3;/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" } # :command.function diff --git a/scripts/cli/src/commands/tools/certs-create.sh b/scripts/cli/src/commands/tools/certs-create.sh index 3287efc9cd..16a944564f 100644 --- a/scripts/cli/src/commands/tools/certs-create.sh +++ b/scripts/cli/src/commands/tools/certs-create.sh @@ -27,4 +27,4 @@ mkdir -p "${output_folder}" cd "${output_folder}" cp $root_folder/scripts/cli/src/ssl/certs-create.sh . log "🔐 Generate keys and certificates in folder ${output_folder}" -docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" \ No newline at end of file + docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "ln -s /usr/local/lib64/libssl.so.3 /usr/lib64/libssl.so.3;ln -s /usr/local/lib64/libcrypto.so.3 /usr/lib64/libcrypto.so.3;/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" \ No newline at end of file From 654784ebb9502949fd7ab41beddc69d1f8dc082f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 12 Feb 2025 13:23:40 +0100 Subject: [PATCH 237/659] playground connector create-or-update --- .../connect-datagen-source/datagen-source.sh | 115 +++++++++--------- 1 file changed, 55 insertions(+), 60 deletions(-) diff --git a/connect/connect-datagen-source/datagen-source.sh b/connect/connect-datagen-source/datagen-source.sh index 4529a7aac2..a0c2b9b0b0 100755 --- a/connect/connect-datagen-source/datagen-source.sh +++ b/connect/connect-datagen-source/datagen-source.sh @@ -15,78 +15,73 @@ playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker- log "Create topic orders" -curl -s -X PUT \ - -H "Content-Type: application/json" \ - --data '{ - "connector.class": "io.confluent.kafka.connect.datagen.DatagenConnector", - "kafka.topic": "orders", - "key.converter": "org.apache.kafka.connect.storage.StringConverter", - "value.converter": "org.apache.kafka.connect.json.JsonConverter", - "value.converter.schemas.enable": "false", - "max.interval": 1, - "iterations": "10000", - "tasks.max": "10", - "schema.filename" : "/tmp/schemas/orders.avro", - "schema.keyfield" : "orderid" - }' \ - http://localhost:8083/connectors/datagen-orders/config | jq . +playground connector create-or-update --connector datagen-orders << EOF +{ + "connector.class": "io.confluent.kafka.connect.datagen.DatagenConnector", + "kafka.topic": "orders", + "key.converter": "org.apache.kafka.connect.storage.StringConverter", + "value.converter": "org.apache.kafka.connect.json.JsonConverter", + "value.converter.schemas.enable": "false", + "max.interval": 1, + "iterations": "10000", + "tasks.max": "10", + "schema.filename" : "/tmp/schemas/orders.avro", + "schema.keyfield" : "orderid" +} +EOF wait_for_datagen_connector_to_inject_data "orders" "10" log "Create topic shipments" -curl -s -X PUT \ - -H "Content-Type: application/json" \ - --data '{ - "connector.class": "io.confluent.kafka.connect.datagen.DatagenConnector", - "kafka.topic": "shipments", - "key.converter": "org.apache.kafka.connect.storage.StringConverter", - "value.converter": "org.apache.kafka.connect.json.JsonConverter", - "value.converter.schemas.enable": "false", - "max.interval": 1, - "iterations": "10000", - "tasks.max": "10", - "schema.filename" : "/tmp/schemas/shipments.avro" - }' \ - http://localhost:8083/connectors/datagen-shipments/config | jq . +playground connector create-or-update --connector datagen-shipments << EOF +{ + "connector.class": "io.confluent.kafka.connect.datagen.DatagenConnector", + "kafka.topic": "shipments", + "key.converter": "org.apache.kafka.connect.storage.StringConverter", + "value.converter": "org.apache.kafka.connect.json.JsonConverter", + "value.converter.schemas.enable": "false", + "max.interval": 1, + "iterations": "10000", + "tasks.max": "10", + "schema.filename" : "/tmp/schemas/shipments.avro" +} +EOF wait_for_datagen_connector_to_inject_data "shipments" "10" log "Create topic products" -curl -s -X PUT \ - -H "Content-Type: application/json" \ - --data '{ - "connector.class": "io.confluent.kafka.connect.datagen.DatagenConnector", - "kafka.topic": "products", - "key.converter": "org.apache.kafka.connect.storage.StringConverter", - "value.converter": "org.apache.kafka.connect.json.JsonConverter", - "value.converter.schemas.enable": "false", - "max.interval": 1, - "iterations": "100", - "tasks.max": "10", - "schema.filename" : "/tmp/schemas/products.avro", - "schema.keyfield" : "productid" - }' \ - http://localhost:8083/connectors/datagen-products/config | jq . +playground connector create-or-update --connector datagen-products << EOF +{ + "connector.class": "io.confluent.kafka.connect.datagen.DatagenConnector", + "kafka.topic": "products", + "key.converter": "org.apache.kafka.connect.storage.StringConverter", + "value.converter": "org.apache.kafka.connect.json.JsonConverter", + "value.converter.schemas.enable": "false", + "max.interval": 1, + "iterations": "100", + "tasks.max": "10", + "schema.filename" : "/tmp/schemas/products.avro", + "schema.keyfield" : "orderid" +} +EOF wait_for_datagen_connector_to_inject_data "products" "10" log "Create topic customers" -curl -s -X PUT \ - -H "Content-Type: application/json" \ - --data '{ - "connector.class": "io.confluent.kafka.connect.datagen.DatagenConnector", - "kafka.topic": "customers", - "key.converter": "org.apache.kafka.connect.storage.StringConverter", - "value.converter": "org.apache.kafka.connect.json.JsonConverter", - "value.converter.schemas.enable": "false", - "max.interval": 1, - "iterations": "1000", - "tasks.max": "10", - "schema.filename" : "/tmp/schemas/customers.avro", - "schema.keyfield" : "customerid" - }' \ - http://localhost:8083/connectors/datagen-customers/config | jq . - +playground connector create-or-update --connector datagen-customers << EOF +{ + "connector.class": "io.confluent.kafka.connect.datagen.DatagenConnector", + "kafka.topic": "customers", + "key.converter": "org.apache.kafka.connect.storage.StringConverter", + "value.converter": "org.apache.kafka.connect.json.JsonConverter", + "value.converter.schemas.enable": "false", + "max.interval": 1, + "iterations": "1000", + "tasks.max": "10", + "schema.filename" : "/tmp/schemas/customers.avro", + "schema.keyfield" : "orderid" +} +EOF wait_for_datagen_connector_to_inject_data "customers" "10" sleep 10 From 5995e8a415a3210535c5c58943d97e6ca0df1158 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 12 Feb 2025 13:33:22 +0100 Subject: [PATCH 238/659] wip --- .../connect-datagen-source/datagen-source.sh | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/connect/connect-datagen-source/datagen-source.sh b/connect/connect-datagen-source/datagen-source.sh index a0c2b9b0b0..1ce8e80eb1 100755 --- a/connect/connect-datagen-source/datagen-source.sh +++ b/connect/connect-datagen-source/datagen-source.sh @@ -43,7 +43,8 @@ playground connector create-or-update --connector datagen-shipments << EOF "max.interval": 1, "iterations": "10000", "tasks.max": "10", - "schema.filename" : "/tmp/schemas/shipments.avro" + "schema.filename" : "/tmp/schemas/shipments.avro", + "schema.keyfield" : "orderid" } EOF @@ -62,7 +63,7 @@ playground connector create-or-update --connector datagen-products << EOF "iterations": "100", "tasks.max": "10", "schema.filename" : "/tmp/schemas/products.avro", - "schema.keyfield" : "orderid" + "schema.keyfield" : "productid" } EOF wait_for_datagen_connector_to_inject_data "products" "10" @@ -79,7 +80,7 @@ playground connector create-or-update --connector datagen-customers << EOF "iterations": "1000", "tasks.max": "10", "schema.filename" : "/tmp/schemas/customers.avro", - "schema.keyfield" : "orderid" + "schema.keyfield" : "customerid" } EOF wait_for_datagen_connector_to_inject_data "customers" "10" @@ -87,13 +88,4 @@ wait_for_datagen_connector_to_inject_data "customers" "10" sleep 10 log "Verify we have received the data in orders topic" -playground topic consume --topic orders --min-expected-messages 1 --timeout 60 - -log "Verify we have received the data in shipments topic" -playground topic consume --topic shipments --min-expected-messages 1 --timeout 60 - -log "Verify we have received the data in customers topic" -playground topic consume --topic customers --min-expected-messages 1 --timeout 60 - -log "Verify we have received the data in products topic" -playground topic consume --topic products --min-expected-messages 1 --timeout 60 +playground topic consume --topic orders --min-expected-messages 1 --timeout 60 \ No newline at end of file From 8b910aba9629fa71f30adb1736e4a03dbab7945f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 12 Feb 2025 13:33:30 +0100 Subject: [PATCH 239/659] wip --- scripts/cli/confluent-hub-plugin-list.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index 4152728bc8..47b2f8203e 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -111,7 +111,6 @@ confluentinc/kafka-connect-tibco-source confluentinc/kafka-connect-vertica confluentinc/kafka-connect-weblogic confluentinc/kafka-connect-zendesk -confluentinc/stream-catalog-connect-collibra couchbase/kafka-connect-couchbase dariobalinzo/kafka-connect-elasticsearch-source databricks/databricks-kafka From c253aad3475bf60e12103759880fa300292ab712 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 12 Feb 2025 14:19:38 +0100 Subject: [PATCH 240/659] fix for mdc --- scripts/cli/playground | 4 ++-- scripts/cli/src/lib/cli_function.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index d3e920ef3d..f003da628b 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -6476,9 +6476,9 @@ function get_connect_url_and_security() { connect_port="8083" - if ! is_container_running "connect" + if ! is_container_running "connect" && ! is_container_running "connect-us" then - if is_container_running "connect2" + if is_container_running "connect2" || is_container_running "connect-europe" then connect_port="8283" # log "💫 using connect rest api for connect2 as connect rest api on port 8083 is not available" diff --git a/scripts/cli/src/lib/cli_function.sh b/scripts/cli/src/lib/cli_function.sh index 225b9615f1..87a9b48085 100644 --- a/scripts/cli/src/lib/cli_function.sh +++ b/scripts/cli/src/lib/cli_function.sh @@ -12,9 +12,9 @@ function get_connect_url_and_security() { connect_port="8083" - if ! is_container_running "connect" + if ! is_container_running "connect" && ! is_container_running "connect-us" then - if is_container_running "connect2" + if is_container_running "connect2" || is_container_running "connect-europe" then connect_port="8283" # log "💫 using connect rest api for connect2 as connect rest api on port 8083 is not available" From e5171a6e422a646e57fa8a69bf019cdd7b094737 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 12 Feb 2025 16:04:41 +0100 Subject: [PATCH 241/659] =?UTF-8?q?=F0=9F=A7=A0=20better=20handling=20of?= =?UTF-8?q?=20=E2=80=93enable-multiple-brokers=20in=20case=20a=20container?= =?UTF-8?q?=20is=20down=20#6303?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 102 +++++++++++------- .../src/commands/connector/offsets/alter.sh | 6 +- .../cli/src/commands/connector/offsets/get.sh | 4 +- .../src/commands/connector/offsets/reset.sh | 4 +- .../cli/src/commands/connector/show-lag.sh | 4 +- scripts/cli/src/commands/get-topic-list.sh | 7 +- scripts/cli/src/commands/topic/alter.sh | 2 +- scripts/cli/src/commands/topic/consume.sh | 6 +- scripts/cli/src/commands/topic/create.sh | 4 +- scripts/cli/src/commands/topic/delete.sh | 4 +- scripts/cli/src/commands/topic/describe.sh | 4 +- .../topic/display-consumer-offsets.sh | 4 +- .../src/commands/topic/get-number-records.sh | 5 +- scripts/cli/src/commands/topic/produce.sh | 6 +- scripts/cli/src/lib/cli_function.sh | 41 +++++-- 15 files changed, 131 insertions(+), 72 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index f003da628b..9853ca7d75 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -6471,6 +6471,17 @@ function is_container_running() { docker inspect -f '{{.State.Running}}' "$container_name" 2>/dev/null | grep -q "true" } +function get_connect_container() { + for worker in connect connect2 connect3 connect-us connect-europe + do + if is_container_running $worker + then + connect_container=$worker + break + fi + done +} + function get_connect_url_and_security() { get_environment_used @@ -6822,11 +6833,24 @@ function get_sr_url_and_security() { fi } +function get_broker_container() { + for broker in broker broker2 broker3 broker-us broker-europe + do + if is_container_running $broker + then + broker_container=$broker + break + fi + done +} + function get_security_broker() { config_file_name="$1" get_environment_used - container="broker" + get_broker_container + container="$broker_container" + security="" if [[ "$environment" == "kerberos" ]] || [[ "$environment" == "ssl_kerberos" ]] then @@ -7440,7 +7464,7 @@ function add_connector_config_based_on_environment () { ;; sasl-ssl) - + get_broker_container for prefix in {"confluent.topic","redo.log.consumer"} do if echo "$json_content" | jq ". | has(\"$prefix.bootstrap.servers\")" 2> /dev/null | grep -q true @@ -7449,7 +7473,7 @@ function add_connector_config_based_on_environment () { # log "replacing $prefix config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"$prefix.bootstrap.servers\"] = \"broker:9092\" | .[\"$prefix.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"$prefix.security.protocol\"] = \"SASL_SSL\" | .[\"$prefix.sasl.mechanism\"] = \"PLAIN\" | .[\"$prefix.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"$prefix.ssl.truststore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"$prefix.bootstrap.servers\"] = \"$broker_container:9092\" | .[\"$prefix.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"$prefix.security.protocol\"] = \"SASL_SSL\" | .[\"$prefix.sasl.mechanism\"] = \"PLAIN\" | .[\"$prefix.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"$prefix.ssl.truststore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi done @@ -7473,7 +7497,7 @@ function add_connector_config_based_on_environment () { # log "replacing database.history.kafka.bootstrap.servers config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"database.history.kafka.bootstrap.servers\"] = \"broker:9092\" | .[\"database.history.producer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"database.history.producer.security.protocol\"] = \"SASL_SSL\" | .[\"database.history.producer.sasl.mechanism\"] = \"PLAIN\" | .[\"database.history.consumer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"database.history.consumer.security.protocol\"] = \"SASL_SSL\" | .[\"database.history.consumer.sasl.mechanism\"] = \"PLAIN\" | .[\"database.history.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.producer.ssl.truststore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.consumer.ssl.truststore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"database.history.kafka.bootstrap.servers\"] = \"$broker_container:9092\" | .[\"database.history.producer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"database.history.producer.security.protocol\"] = \"SASL_SSL\" | .[\"database.history.producer.sasl.mechanism\"] = \"PLAIN\" | .[\"database.history.consumer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"database.history.consumer.security.protocol\"] = \"SASL_SSL\" | .[\"database.history.consumer.sasl.mechanism\"] = \"PLAIN\" | .[\"database.history.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.producer.ssl.truststore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.consumer.ssl.truststore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi @@ -7483,7 +7507,7 @@ function add_connector_config_based_on_environment () { # log "replacing schema.history.internal.kafka.bootstrap.servers config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"schema.history.internal.kafka.bootstrap.servers\"] = \"broker:9092\" | .[\"schema.history.internal.producer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"schema.history.internal.producer.security.protocol\"] = \"SASL_SSL\" | .[\"schema.history.internal.producer.sasl.mechanism\"] = \"PLAIN\" | .[\"schema.history.internal.consumer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"schema.history.internal.consumer.security.protocol\"] = \"SASL_SSL\" | .[\"schema.history.internal.consumer.sasl.mechanism\"] = \"PLAIN\" | .[\"schema.history.internal.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.producer.ssl.truststore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.consumer.ssl.truststore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"schema.history.internal.kafka.bootstrap.servers\"] = \"$broker_container:9092\" | .[\"schema.history.internal.producer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"schema.history.internal.producer.security.protocol\"] = \"SASL_SSL\" | .[\"schema.history.internal.producer.sasl.mechanism\"] = \"PLAIN\" | .[\"schema.history.internal.consumer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"schema.history.internal.consumer.security.protocol\"] = \"SASL_SSL\" | .[\"schema.history.internal.consumer.sasl.mechanism\"] = \"PLAIN\" | .[\"schema.history.internal.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.producer.ssl.truststore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.consumer.ssl.truststore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi @@ -7499,7 +7523,7 @@ function add_connector_config_based_on_environment () { ;; 2way-ssl) - + get_broker_container for prefix in {"confluent.topic","redo.log.consumer"} do if echo "$json_content" | jq ". | has(\"$prefix.bootstrap.servers\")" 2> /dev/null | grep -q true @@ -7508,7 +7532,7 @@ function add_connector_config_based_on_environment () { # log "replacing $prefix config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"$prefix.bootstrap.servers\"] = \"broker:9092\" | .[\"$prefix.security.protocol\"] = \"SSL\" | .[\"$prefix.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"$prefix.ssl.truststore.password\"] = \"confluent\" | .[\"$prefix.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"$prefix.ssl.keystore.password\"] = \"confluent\" | .[\"$prefix.ssl.key.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"$prefix.bootstrap.servers\"] = \"$broker_container:9092\" | .[\"$prefix.security.protocol\"] = \"SSL\" | .[\"$prefix.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"$prefix.ssl.truststore.password\"] = \"confluent\" | .[\"$prefix.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"$prefix.ssl.keystore.password\"] = \"confluent\" | .[\"$prefix.ssl.key.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi done @@ -7532,7 +7556,7 @@ function add_connector_config_based_on_environment () { # log "replacing database.history.kafka.bootstrap.servers config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"database.history.kafka.bootstrap.servers\"] = \"broker:9092\" | .[\"database.history.producer.security.protocol\"] = \"SSL\" | .[\"database.history.consumer.security.protocol\"] = \"SSL\" | .[\"database.history.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.producer.ssl.truststore.password\"] = \"confluent\" | .[\"database.history.producer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"database.history.producer.ssl.keystore.password\"] = \"confluent\" | .[\"database.history.producer.ssl.keystore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.consumer.ssl.truststore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"database.history.consumer.ssl.keystore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.keystore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"database.history.kafka.bootstrap.servers\"] = \"$broker_container:9092\" | .[\"database.history.producer.security.protocol\"] = \"SSL\" | .[\"database.history.consumer.security.protocol\"] = \"SSL\" | .[\"database.history.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.producer.ssl.truststore.password\"] = \"confluent\" | .[\"database.history.producer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"database.history.producer.ssl.keystore.password\"] = \"confluent\" | .[\"database.history.producer.ssl.keystore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.consumer.ssl.truststore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"database.history.consumer.ssl.keystore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.keystore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi @@ -7542,7 +7566,7 @@ function add_connector_config_based_on_environment () { # log "replacing schema.history.internal.kafka.bootstrap.servers config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"schema.history.internal.kafka.bootstrap.servers\"] = \"broker:9092\" | .[\"schema.history.internal.producer.security.protocol\"] = \"SSL\" | .[\"schema.history.internal.consumer.security.protocol\"] = \"SSL\" | .[\"schema.history.internal.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.producer.ssl.truststore.password\"] = \"confluent\" | .[\"schema.history.internal.producer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"schema.history.internal.producer.ssl.keystore.password\"] = \"confluent\" | .[\"schema.history.internal.producer.ssl.keystore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.consumer.ssl.truststore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"schema.history.internal.consumer.ssl.keystore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.keystore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"schema.history.internal.kafka.bootstrap.servers\"] = \"$broker_container:9092\" | .[\"schema.history.internal.producer.security.protocol\"] = \"SSL\" | .[\"schema.history.internal.consumer.security.protocol\"] = \"SSL\" | .[\"schema.history.internal.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.producer.ssl.truststore.password\"] = \"confluent\" | .[\"schema.history.internal.producer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"schema.history.internal.producer.ssl.keystore.password\"] = \"confluent\" | .[\"schema.history.internal.producer.ssl.keystore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.consumer.ssl.truststore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"schema.history.internal.consumer.ssl.keystore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.keystore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi @@ -13006,15 +13030,16 @@ playground_get_topic_list_command() { set -e fi else + get_broker_container # trick to be faster - docker exec broker ls /var/lib/kafka/data > /dev/null 2>&1 + docker exec $broker_container ls /var/lib/kafka/data > /dev/null 2>&1 if [ $? -eq 0 ] then if [[ -n "$skip_connect_internal_topics" ]] then - docker exec broker ls /var/lib/kafka/data | grep -v "checkpoint" | grep -v "meta.properties" | grep -v "connect-" | grep -v "^_" | grep -v "delete" | sed 's/[^-]*$//' | sed 's/.$//' | sort | uniq + docker exec $broker_container ls /var/lib/kafka/data | grep -v "checkpoint" | grep -v "meta.properties" | grep -v "connect-" | grep -v "^_" | grep -v "delete" | sed 's/[^-]*$//' | sed 's/.$//' | sort | uniq else - docker exec broker ls /var/lib/kafka/data | grep -v "checkpoint" | grep -v "meta.properties" | grep -v "^_" | grep -v "delete" | sed 's/[^-]*$//' | sed 's/.$//' | sort | uniq + docker exec $broker_container ls /var/lib/kafka/data | grep -v "checkpoint" | grep -v "meta.properties" | grep -v "^_" | grep -v "delete" | sed 's/[^-]*$//' | sed 's/.$//' | sort | uniq fi fi fi @@ -20193,13 +20218,14 @@ playground_topic_get_number_records_command() { logerror "Could not find current CP version from docker ps" exit 1 fi + get_broker_container if ! version_gt $tag "6.9.9" && [ "$security" != "" ] then # GetOffsetShell does not support security before 7.x get_security_broker "--consumer.config" set +e - docker exec $container timeout 15 kafka-console-consumer --bootstrap-server broker:9092 --topic $topic $security --from-beginning --timeout-ms 15000 2>/dev/null | wc -l | tr -d ' ' + docker exec $container timeout 15 kafka-console-consumer --bootstrap-server $broker_container:9092 --topic $topic $security --from-beginning --timeout-ms 15000 2>/dev/null | wc -l | tr -d ' ' set -e else class_name="kafka.tools.GetOffsetShell" @@ -20207,7 +20233,7 @@ playground_topic_get_number_records_command() { then class_name="org.apache.kafka.tools.GetOffsetShell" fi - docker exec $container kafka-run-class $class_name --broker-list broker:9092 $security --topic $topic --time -1 | awk -F ":" '{sum += $3} END {print sum}' + docker exec $broker_container kafka-run-class $class_name --broker-list $broker_container:9092 $security --topic $topic --time -1 | awk -F ":" '{sum += $3} END {print sum}' fi fi done @@ -20231,9 +20257,9 @@ playground_topic_display_consumer_offsets_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used" - echo "kafka-console-consumer --bootstrap-server broker:9092 --topic __consumer_offsets --from-beginning --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter" $security" + echo "kafka-console-consumer --bootstrap-server $bootstrap_server:9092 --topic __consumer_offsets --from-beginning --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter" $security" fi - docker exec -i $container kafka-console-consumer --bootstrap-server broker:9092 --topic __consumer_offsets --from-beginning --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter" $security | grep -v "_confluent-controlcenter" + docker exec -i $container kafka-console-consumer --bootstrap-server $bootstrap_server:9092 --topic __consumer_offsets --from-beginning --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter" $security | grep -v "_confluent-controlcenter" fi } @@ -20297,9 +20323,9 @@ playground_topic_describe_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used" - echo "kafka-topics --describe --topic $topic --bootstrap-server broker:9092 $security" + echo "kafka-topics --describe --topic $topic --bootstrap-server $bootstrap_server:9092 $security" fi - docker exec $container kafka-topics --describe --topic $topic --bootstrap-server broker:9092 $security + docker exec $container kafka-topics --describe --topic $topic --bootstrap-server $bootstrap_server:9092 $security fi done } @@ -20367,8 +20393,10 @@ playground_topic_consume_command() { get_environment_used get_sr_url_and_security - bootstrap_server="broker:9092" - container="connect" + get_broker_container + bootstrap_server="$broker_container:9092" + get_connect_container + container=$connect_container sr_url_cli="http://schema-registry:8081" security="" if [[ "$environment" == "kerberos" ]] || [[ "$environment" == "ssl_kerberos" ]] @@ -20952,8 +20980,10 @@ playground_topic_produce_command() { get_environment_used get_sr_url_and_security - bootstrap_server="broker:9092" - container="connect" + get_broker_container + bootstrap_server="$broker_container:9092" + get_connect_container + container=$connect_container sr_url_cli="http://schema-registry:8081" security="" if [[ "$environment" == "kerberos" ]] || [[ "$environment" == "ssl_kerberos" ]] @@ -22190,9 +22220,9 @@ playground_topic_create_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used" - echo "kafka-topics --create --topic $topic --bootstrap-server broker:9092 --partitions $nb_partitions $security ${other_args[*]}" + echo "kafka-topics --create --topic $topic --bootstrap-server $bootstrap_server:9092 --partitions $nb_partitions $security ${other_args[*]}" fi - docker exec $container kafka-topics --create --topic $topic --bootstrap-server broker:9092 --partitions $nb_partitions $security ${other_args[*]} + docker exec $container kafka-topics --create --topic $topic --bootstrap-server $bootstrap_server:9092 --partitions $nb_partitions $security ${other_args[*]} fi else logerror "❌ topic $topic already exist !" @@ -22249,9 +22279,9 @@ playground_topic_delete_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used" - echo "kafka-topics --delete --topic $topic --bootstrap-server broker:9092 $security" + echo "kafka-topics --delete --topic $topic --bootstrap-server $bootstrap_server:9092 $security" fi - docker exec $container kafka-topics --delete --topic $topic --bootstrap-server broker:9092 $security + docker exec $container kafka-topics --delete --topic $topic --bootstrap-server $bootstrap_server:9092 $security fi if [[ -n "$skip_delete_schema" ]] @@ -22315,7 +22345,7 @@ playground_topic_alter_command() { get_connect_image docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-configs --alter --entity-type topics --entity-name $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties ${other_args[*]} else - docker exec $container kafka-configs --alter --entity-type topics --entity-name $topic --bootstrap-server broker:9092 $security ${other_args[*]} + docker exec $container kafka-configs --alter --entity-type topics --entity-name $topic --bootstrap-server $bootstrap_server:9092 $security ${other_args[*]} fi fi set -e @@ -22785,7 +22815,7 @@ playground_connector_offsets_get_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used" - echo "kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector --describe $security" + echo "kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector --describe $security" fi get_environment_used if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] || [[ "$environment" == "ccloud" ]] @@ -22801,7 +22831,7 @@ playground_connector_offsets_get_command() { continue fi else - docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector --describe $security + docker exec $container kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector --describe $security fi fi @@ -22947,7 +22977,7 @@ playground_connector_offsets_reset_command() { fi playground connector offsets get --connector $connector else - docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector --describe $security | grep -v PARTITION + docker exec $container kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector --describe $security | grep -v PARTITION if version_gt $tag "7.4.99" then @@ -22957,7 +22987,7 @@ playground_connector_offsets_reset_command() { playground connector delete --connector $connector fi - docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector $security --to-earliest --reset-offsets --all-topics --execute + docker exec $container kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector $security --to-earliest --reset-offsets --all-topics --execute if version_gt $tag "7.4.99" then @@ -23140,7 +23170,7 @@ playground_connector_offsets_alter_command() { # if [[ -n "$verbose" ]] # then # log "🐞 CLI command used" - # echo "kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector --describe $security" + # echo "kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector --describe $security" # fi get_environment_used if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] || [[ "$environment" == "ccloud" ]] @@ -23159,7 +23189,7 @@ playground_connector_offsets_alter_command() { fi echo "topic,partition,current-offset" > $file - docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector $security --export --reset-offsets --to-current --all-topics --dry-run >> $file + docker exec $container kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector $security --export --reset-offsets --to-current --all-topics --dry-run >> $file log "✨ Update the connector offsets as per your needs, save and close the file to continue" playground open --file "${file}" --wait @@ -23169,7 +23199,7 @@ playground_connector_offsets_alter_command() { grep -v 'current-offset' "$file" > $tmp_dir/tmp && mv $tmp_dir/tmp "$file" docker cp $file $container:/tmp/offsets.csv > /dev/null 2>&1 - docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector $security --reset-offsets --from-file /tmp/offsets.csv --execute + docker exec $container kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector $security --reset-offsets --from-file /tmp/offsets.csv --execute if version_gt $tag "7.4.99" then @@ -23809,7 +23839,7 @@ playground_connector_show_lag_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used" - echo "kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector --describe $security" + echo "kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector --describe $security" fi SECONDS=0 @@ -23834,7 +23864,7 @@ playground_connector_show_lag_command() { fi docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SASL_JAAS_CONFIG="$SASL_JAAS_CONFIG" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-consumer-groups --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties --group $consumer_group --describe | grep -v PARTITION | sed '/^$/d' &> $lag_output else - docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector --describe $security | grep -v PARTITION | sed '/^$/d' &> $lag_output + docker exec $container kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector --describe $security | grep -v PARTITION | sed '/^$/d' &> $lag_output fi if grep -q "Warning" $lag_output diff --git a/scripts/cli/src/commands/connector/offsets/alter.sh b/scripts/cli/src/commands/connector/offsets/alter.sh index 627fe1f37a..5ee07fe4ad 100644 --- a/scripts/cli/src/commands/connector/offsets/alter.sh +++ b/scripts/cli/src/commands/connector/offsets/alter.sh @@ -168,7 +168,7 @@ do # if [[ -n "$verbose" ]] # then # log "🐞 CLI command used" - # echo "kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector --describe $security" + # echo "kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector --describe $security" # fi get_environment_used if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] || [[ "$environment" == "ccloud" ]] @@ -187,7 +187,7 @@ do fi echo "topic,partition,current-offset" > $file - docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector $security --export --reset-offsets --to-current --all-topics --dry-run >> $file + docker exec $container kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector $security --export --reset-offsets --to-current --all-topics --dry-run >> $file log "✨ Update the connector offsets as per your needs, save and close the file to continue" playground open --file "${file}" --wait @@ -197,7 +197,7 @@ do grep -v 'current-offset' "$file" > $tmp_dir/tmp && mv $tmp_dir/tmp "$file" docker cp $file $container:/tmp/offsets.csv > /dev/null 2>&1 - docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector $security --reset-offsets --from-file /tmp/offsets.csv --execute + docker exec $container kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector $security --reset-offsets --from-file /tmp/offsets.csv --execute if version_gt $tag "7.4.99" then diff --git a/scripts/cli/src/commands/connector/offsets/get.sh b/scripts/cli/src/commands/connector/offsets/get.sh index 6f4e4129f4..6dafa5249c 100644 --- a/scripts/cli/src/commands/connector/offsets/get.sh +++ b/scripts/cli/src/commands/connector/offsets/get.sh @@ -102,7 +102,7 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used" - echo "kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector --describe $security" + echo "kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector --describe $security" fi get_environment_used if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] || [[ "$environment" == "ccloud" ]] @@ -117,7 +117,7 @@ do continue fi else - docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector --describe $security + docker exec $container kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector --describe $security fi fi fi diff --git a/scripts/cli/src/commands/connector/offsets/reset.sh b/scripts/cli/src/commands/connector/offsets/reset.sh index 5ae95bfb5c..7f28180964 100644 --- a/scripts/cli/src/commands/connector/offsets/reset.sh +++ b/scripts/cli/src/commands/connector/offsets/reset.sh @@ -135,7 +135,7 @@ do fi playground connector offsets get --connector $connector else - docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector --describe $security | grep -v PARTITION + docker exec $container kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector --describe $security | grep -v PARTITION if version_gt $tag "7.4.99" then @@ -145,7 +145,7 @@ do playground connector delete --connector $connector fi - docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector $security --to-earliest --reset-offsets --all-topics --execute + docker exec $container kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector $security --to-earliest --reset-offsets --all-topics --execute if version_gt $tag "7.4.99" then diff --git a/scripts/cli/src/commands/connector/show-lag.sh b/scripts/cli/src/commands/connector/show-lag.sh index 61ff1f09dc..3dd41a140b 100644 --- a/scripts/cli/src/commands/connector/show-lag.sh +++ b/scripts/cli/src/commands/connector/show-lag.sh @@ -195,7 +195,7 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used" - echo "kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector --describe $security" + echo "kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector --describe $security" fi SECONDS=0 @@ -219,7 +219,7 @@ do fi docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SASL_JAAS_CONFIG="$SASL_JAAS_CONFIG" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-consumer-groups --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties --group $consumer_group --describe | grep -v PARTITION | sed '/^$/d' &> $lag_output else - docker exec $container kafka-consumer-groups --bootstrap-server broker:9092 --group connect-$connector --describe $security | grep -v PARTITION | sed '/^$/d' &> $lag_output + docker exec $container kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector --describe $security | grep -v PARTITION | sed '/^$/d' &> $lag_output fi if grep -q "Warning" $lag_output diff --git a/scripts/cli/src/commands/get-topic-list.sh b/scripts/cli/src/commands/get-topic-list.sh index 2be56e35ab..f82db649b6 100644 --- a/scripts/cli/src/commands/get-topic-list.sh +++ b/scripts/cli/src/commands/get-topic-list.sh @@ -15,15 +15,16 @@ then set -e fi else + get_broker_container # trick to be faster - docker exec broker ls /var/lib/kafka/data > /dev/null 2>&1 + docker exec $broker_container ls /var/lib/kafka/data > /dev/null 2>&1 if [ $? -eq 0 ] then if [[ -n "$skip_connect_internal_topics" ]] then - docker exec broker ls /var/lib/kafka/data | grep -v "checkpoint" | grep -v "meta.properties" | grep -v "connect-" | grep -v "^_" | grep -v "delete" | sed 's/[^-]*$//' | sed 's/.$//' | sort | uniq + docker exec $broker_container ls /var/lib/kafka/data | grep -v "checkpoint" | grep -v "meta.properties" | grep -v "connect-" | grep -v "^_" | grep -v "delete" | sed 's/[^-]*$//' | sed 's/.$//' | sort | uniq else - docker exec broker ls /var/lib/kafka/data | grep -v "checkpoint" | grep -v "meta.properties" | grep -v "^_" | grep -v "delete" | sed 's/[^-]*$//' | sed 's/.$//' | sort | uniq + docker exec $broker_container ls /var/lib/kafka/data | grep -v "checkpoint" | grep -v "meta.properties" | grep -v "^_" | grep -v "delete" | sed 's/[^-]*$//' | sed 's/.$//' | sort | uniq fi fi fi \ No newline at end of file diff --git a/scripts/cli/src/commands/topic/alter.sh b/scripts/cli/src/commands/topic/alter.sh index c3880b7d6f..61eb862737 100644 --- a/scripts/cli/src/commands/topic/alter.sh +++ b/scripts/cli/src/commands/topic/alter.sh @@ -35,7 +35,7 @@ else get_connect_image docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-configs --alter --entity-type topics --entity-name $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties ${other_args[*]} else - docker exec $container kafka-configs --alter --entity-type topics --entity-name $topic --bootstrap-server broker:9092 $security ${other_args[*]} + docker exec $container kafka-configs --alter --entity-type topics --entity-name $topic --bootstrap-server $bootstrap_server:9092 $security ${other_args[*]} fi fi set -e diff --git a/scripts/cli/src/commands/topic/consume.sh b/scripts/cli/src/commands/topic/consume.sh index f6602b85ef..214bdc2d5a 100644 --- a/scripts/cli/src/commands/topic/consume.sh +++ b/scripts/cli/src/commands/topic/consume.sh @@ -23,8 +23,10 @@ fi get_environment_used get_sr_url_and_security -bootstrap_server="broker:9092" -container="connect" +get_broker_container +bootstrap_server="$broker_container:9092" +get_connect_container +container=$connect_container sr_url_cli="http://schema-registry:8081" security="" if [[ "$environment" == "kerberos" ]] || [[ "$environment" == "ssl_kerberos" ]] diff --git a/scripts/cli/src/commands/topic/create.sh b/scripts/cli/src/commands/topic/create.sh index 2297a01d06..96fda6e2a0 100644 --- a/scripts/cli/src/commands/topic/create.sh +++ b/scripts/cli/src/commands/topic/create.sh @@ -40,9 +40,9 @@ then if [[ -n "$verbose" ]] then log "🐞 CLI command used" - echo "kafka-topics --create --topic $topic --bootstrap-server broker:9092 --partitions $nb_partitions $security ${other_args[*]}" + echo "kafka-topics --create --topic $topic --bootstrap-server $bootstrap_server:9092 --partitions $nb_partitions $security ${other_args[*]}" fi - docker exec $container kafka-topics --create --topic $topic --bootstrap-server broker:9092 --partitions $nb_partitions $security ${other_args[*]} + docker exec $container kafka-topics --create --topic $topic --bootstrap-server $bootstrap_server:9092 --partitions $nb_partitions $security ${other_args[*]} fi else logerror "❌ topic $topic already exist !" diff --git a/scripts/cli/src/commands/topic/delete.sh b/scripts/cli/src/commands/topic/delete.sh index bbad6e45d8..c3a4393fc0 100644 --- a/scripts/cli/src/commands/topic/delete.sh +++ b/scripts/cli/src/commands/topic/delete.sh @@ -44,9 +44,9 @@ else if [[ -n "$verbose" ]] then log "🐞 CLI command used" - echo "kafka-topics --delete --topic $topic --bootstrap-server broker:9092 $security" + echo "kafka-topics --delete --topic $topic --bootstrap-server $bootstrap_server:9092 $security" fi - docker exec $container kafka-topics --delete --topic $topic --bootstrap-server broker:9092 $security + docker exec $container kafka-topics --delete --topic $topic --bootstrap-server $bootstrap_server:9092 $security fi if [[ -n "$skip_delete_schema" ]] diff --git a/scripts/cli/src/commands/topic/describe.sh b/scripts/cli/src/commands/topic/describe.sh index 254d67546d..09701205e9 100644 --- a/scripts/cli/src/commands/topic/describe.sh +++ b/scripts/cli/src/commands/topic/describe.sh @@ -48,8 +48,8 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used" - echo "kafka-topics --describe --topic $topic --bootstrap-server broker:9092 $security" + echo "kafka-topics --describe --topic $topic --bootstrap-server $bootstrap_server:9092 $security" fi - docker exec $container kafka-topics --describe --topic $topic --bootstrap-server broker:9092 $security + docker exec $container kafka-topics --describe --topic $topic --bootstrap-server $bootstrap_server:9092 $security fi done \ No newline at end of file diff --git a/scripts/cli/src/commands/topic/display-consumer-offsets.sh b/scripts/cli/src/commands/topic/display-consumer-offsets.sh index 5b4e8a290b..7920ab2a89 100644 --- a/scripts/cli/src/commands/topic/display-consumer-offsets.sh +++ b/scripts/cli/src/commands/topic/display-consumer-offsets.sh @@ -12,7 +12,7 @@ else if [[ -n "$verbose" ]] then log "🐞 CLI command used" - echo "kafka-console-consumer --bootstrap-server broker:9092 --topic __consumer_offsets --from-beginning --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter" $security" + echo "kafka-console-consumer --bootstrap-server $bootstrap_server:9092 --topic __consumer_offsets --from-beginning --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter" $security" fi - docker exec -i $container kafka-console-consumer --bootstrap-server broker:9092 --topic __consumer_offsets --from-beginning --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter" $security | grep -v "_confluent-controlcenter" + docker exec -i $container kafka-console-consumer --bootstrap-server $bootstrap_server:9092 --topic __consumer_offsets --from-beginning --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter" $security | grep -v "_confluent-controlcenter" fi \ No newline at end of file diff --git a/scripts/cli/src/commands/topic/get-number-records.sh b/scripts/cli/src/commands/topic/get-number-records.sh index bda95fc94f..baf6732873 100644 --- a/scripts/cli/src/commands/topic/get-number-records.sh +++ b/scripts/cli/src/commands/topic/get-number-records.sh @@ -92,13 +92,14 @@ do logerror "Could not find current CP version from docker ps" exit 1 fi + get_broker_container if ! version_gt $tag "6.9.9" && [ "$security" != "" ] then # GetOffsetShell does not support security before 7.x get_security_broker "--consumer.config" set +e - docker exec $container timeout 15 kafka-console-consumer --bootstrap-server broker:9092 --topic $topic $security --from-beginning --timeout-ms 15000 2>/dev/null | wc -l | tr -d ' ' + docker exec $container timeout 15 kafka-console-consumer --bootstrap-server $broker_container:9092 --topic $topic $security --from-beginning --timeout-ms 15000 2>/dev/null | wc -l | tr -d ' ' set -e else class_name="kafka.tools.GetOffsetShell" @@ -106,7 +107,7 @@ do then class_name="org.apache.kafka.tools.GetOffsetShell" fi - docker exec $container kafka-run-class $class_name --broker-list broker:9092 $security --topic $topic --time -1 | awk -F ":" '{sum += $3} END {print sum}' + docker exec $broker_container kafka-run-class $class_name --broker-list $broker_container:9092 $security --topic $topic --time -1 | awk -F ":" '{sum += $3} END {print sum}' fi fi done diff --git a/scripts/cli/src/commands/topic/produce.sh b/scripts/cli/src/commands/topic/produce.sh index 8b8997e738..bb94d84e8d 100644 --- a/scripts/cli/src/commands/topic/produce.sh +++ b/scripts/cli/src/commands/topic/produce.sh @@ -82,8 +82,10 @@ fi get_environment_used get_sr_url_and_security -bootstrap_server="broker:9092" -container="connect" +get_broker_container +bootstrap_server="$broker_container:9092" +get_connect_container +container=$connect_container sr_url_cli="http://schema-registry:8081" security="" if [[ "$environment" == "kerberos" ]] || [[ "$environment" == "ssl_kerberos" ]] diff --git a/scripts/cli/src/lib/cli_function.sh b/scripts/cli/src/lib/cli_function.sh index 87a9b48085..2f1b18e651 100644 --- a/scripts/cli/src/lib/cli_function.sh +++ b/scripts/cli/src/lib/cli_function.sh @@ -7,6 +7,17 @@ function is_container_running() { docker inspect -f '{{.State.Running}}' "$container_name" 2>/dev/null | grep -q "true" } +function get_connect_container() { + for worker in connect connect2 connect3 connect-us connect-europe + do + if is_container_running $worker + then + connect_container=$worker + break + fi + done +} + function get_connect_url_and_security() { get_environment_used @@ -360,12 +371,24 @@ function get_sr_url_and_security() { fi } +function get_broker_container() { + for broker in broker broker2 broker3 broker-us broker-europe + do + if is_container_running $broker + then + broker_container=$broker + break + fi + done +} + function get_security_broker() { config_file_name="$1" get_environment_used + get_broker_container + container="$broker_container" - container="broker" security="" if [[ "$environment" == "kerberos" ]] || [[ "$environment" == "ssl_kerberos" ]] then @@ -972,7 +995,7 @@ function add_connector_config_based_on_environment () { ;; sasl-ssl) - + get_broker_container for prefix in {"confluent.topic","redo.log.consumer"} do if echo "$json_content" | jq ". | has(\"$prefix.bootstrap.servers\")" 2> /dev/null | grep -q true @@ -980,7 +1003,7 @@ function add_connector_config_based_on_environment () { # log "replacing $prefix config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"$prefix.bootstrap.servers\"] = \"broker:9092\" | .[\"$prefix.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"$prefix.security.protocol\"] = \"SASL_SSL\" | .[\"$prefix.sasl.mechanism\"] = \"PLAIN\" | .[\"$prefix.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"$prefix.ssl.truststore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"$prefix.bootstrap.servers\"] = \"$broker_container:9092\" | .[\"$prefix.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"$prefix.security.protocol\"] = \"SASL_SSL\" | .[\"$prefix.sasl.mechanism\"] = \"PLAIN\" | .[\"$prefix.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"$prefix.ssl.truststore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi done @@ -1002,7 +1025,7 @@ function add_connector_config_based_on_environment () { # log "replacing database.history.kafka.bootstrap.servers config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"database.history.kafka.bootstrap.servers\"] = \"broker:9092\" | .[\"database.history.producer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"database.history.producer.security.protocol\"] = \"SASL_SSL\" | .[\"database.history.producer.sasl.mechanism\"] = \"PLAIN\" | .[\"database.history.consumer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"database.history.consumer.security.protocol\"] = \"SASL_SSL\" | .[\"database.history.consumer.sasl.mechanism\"] = \"PLAIN\" | .[\"database.history.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.producer.ssl.truststore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.consumer.ssl.truststore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"database.history.kafka.bootstrap.servers\"] = \"$broker_container:9092\" | .[\"database.history.producer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"database.history.producer.security.protocol\"] = \"SASL_SSL\" | .[\"database.history.producer.sasl.mechanism\"] = \"PLAIN\" | .[\"database.history.consumer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"database.history.consumer.security.protocol\"] = \"SASL_SSL\" | .[\"database.history.consumer.sasl.mechanism\"] = \"PLAIN\" | .[\"database.history.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.producer.ssl.truststore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.consumer.ssl.truststore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi @@ -1011,7 +1034,7 @@ function add_connector_config_based_on_environment () { # log "replacing schema.history.internal.kafka.bootstrap.servers config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"schema.history.internal.kafka.bootstrap.servers\"] = \"broker:9092\" | .[\"schema.history.internal.producer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"schema.history.internal.producer.security.protocol\"] = \"SASL_SSL\" | .[\"schema.history.internal.producer.sasl.mechanism\"] = \"PLAIN\" | .[\"schema.history.internal.consumer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"schema.history.internal.consumer.security.protocol\"] = \"SASL_SSL\" | .[\"schema.history.internal.consumer.sasl.mechanism\"] = \"PLAIN\" | .[\"schema.history.internal.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.producer.ssl.truststore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.consumer.ssl.truststore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"schema.history.internal.kafka.bootstrap.servers\"] = \"$broker_container:9092\" | .[\"schema.history.internal.producer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"schema.history.internal.producer.security.protocol\"] = \"SASL_SSL\" | .[\"schema.history.internal.producer.sasl.mechanism\"] = \"PLAIN\" | .[\"schema.history.internal.consumer.sasl.jaas.config\"] = \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"client\\\" password=\\\"client-secret\\\";\" | .[\"schema.history.internal.consumer.security.protocol\"] = \"SASL_SSL\" | .[\"schema.history.internal.consumer.sasl.mechanism\"] = \"PLAIN\" | .[\"schema.history.internal.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.producer.ssl.truststore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.consumer.ssl.truststore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi @@ -1026,7 +1049,7 @@ function add_connector_config_based_on_environment () { ;; 2way-ssl) - + get_broker_container for prefix in {"confluent.topic","redo.log.consumer"} do if echo "$json_content" | jq ". | has(\"$prefix.bootstrap.servers\")" 2> /dev/null | grep -q true @@ -1034,7 +1057,7 @@ function add_connector_config_based_on_environment () { # log "replacing $prefix config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"$prefix.bootstrap.servers\"] = \"broker:9092\" | .[\"$prefix.security.protocol\"] = \"SSL\" | .[\"$prefix.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"$prefix.ssl.truststore.password\"] = \"confluent\" | .[\"$prefix.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"$prefix.ssl.keystore.password\"] = \"confluent\" | .[\"$prefix.ssl.key.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"$prefix.bootstrap.servers\"] = \"$broker_container:9092\" | .[\"$prefix.security.protocol\"] = \"SSL\" | .[\"$prefix.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"$prefix.ssl.truststore.password\"] = \"confluent\" | .[\"$prefix.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"$prefix.ssl.keystore.password\"] = \"confluent\" | .[\"$prefix.ssl.key.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi done @@ -1056,7 +1079,7 @@ function add_connector_config_based_on_environment () { # log "replacing database.history.kafka.bootstrap.servers config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"database.history.kafka.bootstrap.servers\"] = \"broker:9092\" | .[\"database.history.producer.security.protocol\"] = \"SSL\" | .[\"database.history.consumer.security.protocol\"] = \"SSL\" | .[\"database.history.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.producer.ssl.truststore.password\"] = \"confluent\" | .[\"database.history.producer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"database.history.producer.ssl.keystore.password\"] = \"confluent\" | .[\"database.history.producer.ssl.keystore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.consumer.ssl.truststore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"database.history.consumer.ssl.keystore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.keystore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"database.history.kafka.bootstrap.servers\"] = \"$broker_container:9092\" | .[\"database.history.producer.security.protocol\"] = \"SSL\" | .[\"database.history.consumer.security.protocol\"] = \"SSL\" | .[\"database.history.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.producer.ssl.truststore.password\"] = \"confluent\" | .[\"database.history.producer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"database.history.producer.ssl.keystore.password\"] = \"confluent\" | .[\"database.history.producer.ssl.keystore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"database.history.consumer.ssl.truststore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"database.history.consumer.ssl.keystore.password\"] = \"confluent\" | .[\"database.history.consumer.ssl.keystore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi @@ -1065,7 +1088,7 @@ function add_connector_config_based_on_environment () { # log "replacing schema.history.internal.kafka.bootstrap.servers config for environment $environment" echo "$json_content" > $tmp_dir/input.json - jq ".[\"schema.history.internal.kafka.bootstrap.servers\"] = \"broker:9092\" | .[\"schema.history.internal.producer.security.protocol\"] = \"SSL\" | .[\"schema.history.internal.consumer.security.protocol\"] = \"SSL\" | .[\"schema.history.internal.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.producer.ssl.truststore.password\"] = \"confluent\" | .[\"schema.history.internal.producer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"schema.history.internal.producer.ssl.keystore.password\"] = \"confluent\" | .[\"schema.history.internal.producer.ssl.keystore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.consumer.ssl.truststore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"schema.history.internal.consumer.ssl.keystore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.keystore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json + jq ".[\"schema.history.internal.kafka.bootstrap.servers\"] = \"$broker_container:9092\" | .[\"schema.history.internal.producer.security.protocol\"] = \"SSL\" | .[\"schema.history.internal.consumer.security.protocol\"] = \"SSL\" | .[\"schema.history.internal.producer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.producer.ssl.truststore.password\"] = \"confluent\" | .[\"schema.history.internal.producer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"schema.history.internal.producer.ssl.keystore.password\"] = \"confluent\" | .[\"schema.history.internal.producer.ssl.keystore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.truststore.location\"] = \"/etc/kafka/secrets/kafka.connect.truststore.jks\" | .[\"schema.history.internal.consumer.ssl.truststore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.keystore.location\"] = \"/etc/kafka/secrets/kafka.connect.keystore.jks\" | .[\"schema.history.internal.consumer.ssl.keystore.password\"] = \"confluent\" | .[\"schema.history.internal.consumer.ssl.keystore.password\"] = \"confluent\"" $tmp_dir/input.json > $tmp_dir/output.json json_content=$(cat $tmp_dir/output.json) fi From 6317d14818b28f4b36661230b34fe84255c09dd0 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 13 Feb 2025 11:08:58 +0100 Subject: [PATCH 242/659] =?UTF-8?q?=F0=9F=90=9B=20Unable=20to=20update=20d?= =?UTF-8?q?ynamic=20config=20#6270?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- environment/plaintext/docker-compose.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/environment/plaintext/docker-compose.yml b/environment/plaintext/docker-compose.yml index 235207a719..b34fd00825 100644 --- a/environment/plaintext/docker-compose.yml +++ b/environment/plaintext/docker-compose.yml @@ -234,6 +234,7 @@ services: # JAVA_DEBUG_OPTS: '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005' # uncomment when investigating class not found issue, see https://kafka-docker-playground.io/#/reusables?id=🔬-class-loading # KAFKA_OPTS: '-verbose:class' + KAFKA_OPTS: -Ddynamic.worker.config.file=/dev/null # Reduce Connect memory utilization EXTRA_ARGS: ${GRAFANA_AGENT_CONNECT} # KAFKA_JVM_PERFORMANCE_OPTS: -server -XX:+UseG1GC -XX:GCTimeRatio=1 @@ -305,6 +306,7 @@ services: # JAVA_DEBUG_OPTS: '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005' # uncomment when investigating class not found issue, see https://kafka-docker-playground.io/#/reusables?id=🔬-class-loading # KAFKA_OPTS: '-verbose:class' + KAFKA_OPTS: -Ddynamic.worker.config.file=/dev/null # Reduce Connect memory utilization EXTRA_ARGS: ${GRAFANA_AGENT_CONNECT} # KAFKA_JVM_PERFORMANCE_OPTS: -server -XX:+UseG1GC -XX:GCTimeRatio=1 @@ -376,6 +378,7 @@ services: # JAVA_DEBUG_OPTS: '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005' # uncomment when investigating class not found issue, see https://kafka-docker-playground.io/#/reusables?id=🔬-class-loading # KAFKA_OPTS: '-verbose:class' + KAFKA_OPTS: -Ddynamic.worker.config.file=/dev/null # Reduce Connect memory utilization EXTRA_ARGS: ${GRAFANA_AGENT_CONNECT} # KAFKA_JVM_PERFORMANCE_OPTS: -server -XX:+UseG1GC -XX:GCTimeRatio=1 From 0d972d30b7b772970f7027d0091362d13466abce Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 13 Feb 2025 14:03:05 +0100 Subject: [PATCH 243/659] remove ssl workaround --- scripts/cli/playground | 2 +- scripts/cli/src/commands/tools/certs-create.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 9853ca7d75..829a112e15 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -19290,7 +19290,7 @@ playground_tools_certs_create_command() { cd "${output_folder}" cp $root_folder/scripts/cli/src/ssl/certs-create.sh . log "🔐 Generate keys and certificates in folder ${output_folder}" - docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "ln -s /usr/local/lib64/libssl.so.3 /usr/lib64/libssl.so.3;ln -s /usr/local/lib64/libcrypto.so.3 /usr/lib64/libcrypto.so.3;/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" + docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" } # :command.function diff --git a/scripts/cli/src/commands/tools/certs-create.sh b/scripts/cli/src/commands/tools/certs-create.sh index 16a944564f..6bee9114ea 100644 --- a/scripts/cli/src/commands/tools/certs-create.sh +++ b/scripts/cli/src/commands/tools/certs-create.sh @@ -27,4 +27,4 @@ mkdir -p "${output_folder}" cd "${output_folder}" cp $root_folder/scripts/cli/src/ssl/certs-create.sh . log "🔐 Generate keys and certificates in folder ${output_folder}" - docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "ln -s /usr/local/lib64/libssl.so.3 /usr/lib64/libssl.so.3;ln -s /usr/local/lib64/libcrypto.so.3 /usr/lib64/libcrypto.so.3;/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" \ No newline at end of file + docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" \ No newline at end of file From f28b269c4253aaab26ad6dac13a73792fd4a5c84 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 13 Feb 2025 15:59:35 +0100 Subject: [PATCH 244/659] node:4-node20-core-tools --- .../fully-managed-azure-functions-sink.sh | 6 +++--- .../connect-azure-functions-sink/azure-functions-sink.sh | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh b/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh index f984c732d9..151eb534b1 100755 --- a/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh +++ b/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh @@ -65,7 +65,7 @@ fi log "Creating local functions project with HTTP trigger" # https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-azure-function-azure-cli?pivots=programming-language-javascript&tabs=bash%2Cbrowser -docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "func init LocalFunctionProj --javascript && cd LocalFunctionProj && func new --name HttpExample --template \"HTTP trigger\" --authlevel \"anonymous\"" +docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node20-core-tools bash -c "func init LocalFunctionProj --javascript && cd LocalFunctionProj && func new --name HttpExample --template \"HTTP trigger\" --authlevel \"anonymous\"" log "Creating functions app $AZURE_FUNCTIONS_NAME" az functionapp create --consumption-plan-location $AZURE_REGION --name $AZURE_FUNCTIONS_NAME --resource-group $AZURE_RESOURCE_GROUP --runtime node --storage-account $AZURE_STORAGE_NAME --runtime-version 18 --functions-version 4 --tags owner_email=$AZ_USER --disable-app-insights true @@ -75,7 +75,7 @@ max_attempts="10" sleep_interval="60" attempt_num=1 -until docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp publish \"$AZURE_FUNCTIONS_NAME\"" +until docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node20-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp publish \"$AZURE_FUNCTIONS_NAME\"" do if (( attempt_num == max_attempts )) then @@ -94,7 +94,7 @@ attempt_num=1 until [ ! -z "$FUNCTIONS_URL" ] do - output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions $AZURE_FUNCTIONS_NAME --show-keys") + output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node20-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions $AZURE_FUNCTIONS_NAME --show-keys") FUNCTIONS_URL=$(echo "$output" | grep "Invoke url" | grep -Eo 'https://[^ >]+' | head -1) if [ ! -z "$FUNCTIONS_URL" ] diff --git a/connect/connect-azure-functions-sink/azure-functions-sink.sh b/connect/connect-azure-functions-sink/azure-functions-sink.sh index 89cf1faede..98e5089199 100755 --- a/connect/connect-azure-functions-sink/azure-functions-sink.sh +++ b/connect/connect-azure-functions-sink/azure-functions-sink.sh @@ -65,7 +65,7 @@ fi log "Creating local functions project with HTTP trigger" # https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-azure-function-azure-cli?pivots=programming-language-javascript&tabs=bash%2Cbrowser -docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "func init LocalFunctionProj --javascript && cd LocalFunctionProj && func new --name HttpExample --template \"HTTP trigger\" --authlevel \"anonymous\"" +docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node20-core-tools bash -c "func init LocalFunctionProj --javascript && cd LocalFunctionProj && func new --name HttpExample --template \"HTTP trigger\" --authlevel \"anonymous\"" log "Creating functions app $AZURE_FUNCTIONS_NAME" az functionapp create --consumption-plan-location "$AZURE_REGION" --name "$AZURE_FUNCTIONS_NAME" --resource-group "$AZURE_RESOURCE_GROUP" --runtime node --storage-account "$AZURE_STORAGE_NAME" --runtime-version 18 --functions-version 4 --tags owner_email="$AZ_USER" --disable-app-insights true @@ -86,7 +86,7 @@ max_attempts="10" sleep_interval="60" attempt_num=1 -until docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp publish \"$AZURE_FUNCTIONS_NAME\"" +until docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node20-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp publish \"$AZURE_FUNCTIONS_NAME\"" do if (( attempt_num == max_attempts )) then @@ -111,7 +111,7 @@ attempt_num=1 until [ ! -z "$FUNCTIONS_URL" ] do - output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node14-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions \"$AZURE_FUNCTIONS_NAME\" --show-keys") + output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node20-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions \"$AZURE_FUNCTIONS_NAME\" --show-keys") log "Output from list-functions command: $output" From 3165d22f2efbbbf541417245e08108ffa348da79 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 18 Feb 2025 10:30:53 +0100 Subject: [PATCH 245/659] minor --- scripts/cli/playground | 3 ++- .../cli/src/commands/container/set-environment-variables.sh | 3 ++- scripts/cli/src/commands/topic/produce.sh | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 829a112e15..c0d62d796b 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -20099,6 +20099,7 @@ EOF load_env_variables bash $tmp_dir/playground-command fi + wait_container_ready } # :command.function @@ -22080,7 +22081,7 @@ playground_topic_produce_command() { fi else # 🧠 remove SLF4J traces from topic produce #6254 - playground container exec --command "rm -f /usr/share/java/schema-registry/slf4j-reload4j-1.7.36.jar > /dev/null 2>&1" --root + playground --output-level ERROR container exec --command "rm -f /usr/share/java/schema-registry/slf4j-reload4j-1.7.36.jar > /dev/null 2>&1" --root if [ -f $key_schema_file ] then docker cp $key_schema_file $container:/tmp/key_schema_file > /dev/null 2>&1 diff --git a/scripts/cli/src/commands/container/set-environment-variables.sh b/scripts/cli/src/commands/container/set-environment-variables.sh index 90c45f2214..1cc4537c33 100644 --- a/scripts/cli/src/commands/container/set-environment-variables.sh +++ b/scripts/cli/src/commands/container/set-environment-variables.sh @@ -69,4 +69,5 @@ else echo "$docker_command" > $tmp_dir/playground-command load_env_variables bash $tmp_dir/playground-command -fi \ No newline at end of file +fi +wait_container_ready \ No newline at end of file diff --git a/scripts/cli/src/commands/topic/produce.sh b/scripts/cli/src/commands/topic/produce.sh index bb94d84e8d..e2f6c7d076 100644 --- a/scripts/cli/src/commands/topic/produce.sh +++ b/scripts/cli/src/commands/topic/produce.sh @@ -1173,7 +1173,7 @@ do fi else # 🧠 remove SLF4J traces from topic produce #6254 - playground container exec --command "rm -f /usr/share/java/schema-registry/slf4j-reload4j-1.7.36.jar > /dev/null 2>&1" --root + playground --output-level ERROR container exec --command "rm -f /usr/share/java/schema-registry/slf4j-reload4j-1.7.36.jar > /dev/null 2>&1" --root if [ -f $key_schema_file ] then docker cp $key_schema_file $container:/tmp/key_schema_file > /dev/null 2>&1 From 1ade7c1e9cabf82849c93b1b215b06e22860d11c Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 18 Feb 2025 11:13:20 +0100 Subject: [PATCH 246/659] wip --- secrets.tar.gpg | Bin 7834 -> 7832 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/secrets.tar.gpg b/secrets.tar.gpg index ca3bef27d8ac745f1de8e9f770c182b0762b65ba..535396e3b0d0c888bb8baa6418a7a8801b1f2441 100644 GIT binary patch literal 7832 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 literal 7834 zcmV;L9%bQ-4Fm}T0>GL`E2hfI67bUM0kPQBfVFVQ<_fHK#n|sVegZ=5gt(e7%W)O& z4R+tuL6Ixi&3{P%5TOwfN4K8GJRA|!skIG_Ket0Q)=!rtxjIm*l#RNZ=&v7R;~?Gw{3dO4FI5Mf?>`0@xE{X3z03Wt@IXkn1A>R(|;m@R&JGQjTx{1%^ce4 zRnk~^oAe9#v`P`(8&_uXh!se=RtOHIums8pyc&66|K{ueA zP)wE3snR3E8u2hkMiopX#r~VM65t&Kf<%{wB1pm`ChT28Bv>3u4=oGkWfR9y;2JE08-D+tfKrYtB*Sn~|VGT_n6r>Z32LQ8Pn_9BPMS7fUhLq?|O&-v{AD&bMyhDXLO{P|6X*41e z*KCd?%dq-F%%qrzXvKy0MDGvT7;vkq1c0*hAhcr%@?|1gDjDD@%mA<5C%kZ$B}i%5 z_hde<0zEXhY&%_hy;?;%qNeWJNla(L#L~I#4Q?%QyUXdL5wNj+Odnbm8s{8Ne<0io zRaGSr%V!zWLC)e+IyK6CT2a4{l@2D&3X9jdGS8w29Y9-tYF~N)@2!)5Qk%wTsIMS( zh~>W9SGg`Q@$XG$iXcpADHzDx%+jL2MRS}uD9l5j)- z+>d=8&56nVK!v$6>lxP$Qe)n#iV&GZ2S4Fmma;jZsX)Ilp*$o+8y>$P%`CrL4~`1YtnL7<=eQ@# z9Vl6SY-PeV>ewIpOAy;c*`-!3& zDu8xN%SX#N7+_fL0l%d~+?FY3LrNM$P&1omvAvt(bYk)=z;Ex}kTs{dn}-)Y#U(?n z)tS&vz*C1CK_5TiuAjHo$9HCySiUEY@5md1r8c9Ay2R9!0|(xo1pNoiP&+5?*KMkh zgSsn?w~*&Ch`fm_Tt#m_VK?V>@LJAO&BdtxW@f2tQ!z?YNHATS+EQ@PtI;)d;vs9? zZYo4{y+;uVoUGki_+U{g&+KYMCJCN*W=Xlj^2@mVjRQI1D9>kHJ&xAd&C-ylWs-^; ze!W+DLtFNN91zyxnOpJ4$qpiNM9^yQH_x$)r;7!xFY!y?0x{~MVl;)vHP|CWBn^#Av4+P$r#ac0a-kkv~>)txWJd?uyNAwCc84be59XO(lUHXU;Ku{klZSm^eiu?deBbwB^q0?1a8DjXLIM)c;WDG9J zLv({Ik`Q@O0V&J$#(EV@Tv#j~naAPp(j*kI(n*0}~1& zpf6<6IFW-k%s78LJaA+H#Z}EeG(uHQPSk9om1k(2Y1_afkfQv&UkQkcSDS)$E<%O>C8^H?9dydMzVh|xiw@TLqMAy$=8^9?Sk z+6S70*b|HcOd0!1IrVrsD`h58VM1Vazvb`%j*H`4yQmoK(&cP_BPQClYb7vviYti;4J?DgmEY- zk8=jk>&pFC%~O)^=N zSjfCeo8*rFKLtfj!#3#UGxcZx7-Mtvb=1e=1#}mb-&z&5Slm#eGqrEUJV4@$Q)M{U zRHbT9ji#1L%7mtW-ym2kt#f;$HKcSCbiY1;nC)WA*Hh6LZM@%KGOeceKkWJsQ|*WV zKryg?UlD}>8BRy7WD`|7htpP`@6fOA8`vj<=BEE7+0xiR{afcSQm(Ynr2KI96=sv> zr?skMLK***vro>u^w*t9V8PF3OlWMWg&m3_De3k}&C%#DrfU9yAQKWwRAv<43odQi z8av1KsHxQEH(mY(1z zg5$o!OfVkprP|w-lEg;i2HevU1qG{2c`=)bQQ4Bt{wtE8M<4? z>b}6%PB6dMyy8J=4Ostw`HmMt^`@3OAxllOGD~%95>7NLCp71L;yiq3!rwY@2ORTe zqJ-l1|TCeWLE6 z0l@J3?X3rrb^6d6-=P8$B#Pr=;6m{WX3=z@)O>4}uZ`n^+d+Lk$*9g%`AyhGZVVTE zABlb<^9y_zxEv(A;vGp|DXh<-OGX7e%%9D%C{8si1Ju{Q9zF#&o_BgvGiVX4MO>E> ze|aDPZ%_k8=&xhf{B7;OA76g-v0x7vQddgDbzhZW_1PR@$=pVQHXCGDmG(kpTrO4|NAQ065;&P}>ph%u^T3g3MXn6N7<69ULmirYbEyJlP}xay8QySG(_@Pz%!zyS{wln5ojMyogzgYYAk8M3DWX z`R}wg64vntuFN6b^@c%LW8;IN5w&ljxt@XciT#&3oEhyIvrp|@T~gHfOsP8~lJ*B&9IEXh|)&1zFfL&6lYXIbb$ z{@$JHMO@cy~qf9}Ljb{&^?||Hva{zNwIXEfu%OY+>l#4^f-l>K{%? zzMcX+TG!hY6H(+GUr3nED|cd0?SxsGAx}fq}th(NF5wco7$7Ao_IXC=$$fOzI;e zGE_EpQC*g3>&IR}Fw2dNJ7NnDg|^@f0r}Z`JwI~&_@VU1SW-$6iW8TEekuHGJw?ex z*eMB?BW=TJV8c)ZXM>U9!hjp*ys|a85?fmv{lk{Ahk)flHvCh%y_MM^%_l-2;Rk*p zGKykv6kap^@@m_-T{wKwY5EqgK{L0HP1)SePei(u?+PnT$-P?=+HYR3K}_S>KxT|H z(6S?}%e@8BU4lxN)spL{E`n$_n|=hAedONRceri=3&T9vg)Z5=veo|y1#emn+8qPN zK}0d9h(aPdKj9hH`fdopI@EjK$!PbmdEkou!I+DycvF+JANbQXtT+(PY-+L(TYGdU zu<#!7SIn%}Z+A1an!_S}qYJP|n0yK@h7G`tuAS=w4v>@9SnwR54tT(ZAJOY@4H0cA zEeYM=uT&Mjsm<0_*G)r@>CLWdSiQ~(KtztVY_{#iH(^f0Off12q2A}X7z$!>6oeRD z2pYRT!MJCm7+{EVD?hoQs}KTdsWvYMVoN9&9BQD{+#*Bd79NhC5=TkG0~tpmx0IpY zM`Oon?u=ODI7|Lzx*?>nGcH z6Vh0|ouNc|+WW61+aG(EUP!XI{D(hl_)(e(xlHIU%wiR8tR!VP&r+8eIRp)&(Az(MuO^7rV$Yv&Lq$6j5{9a4eE(pCJ{>GZ7@>G~5 z${gyNS^81}Vfg)iFJy8OgkE?qn8w_*d8$|?O#zokoKW#EElrMUFMhJyaMQe685xYg zm)T!6pRGWbl}vAjK>QW)AuXIQBTp@i)9x5N>MwvIg2-43jIvW(<-R;{QWed#rH{UA zQLX!q9z_NRqqw5-yxBN4Od7Nn!RMwCc&0lj?NfC~Kw2wwz#iaMINLi>>MBk=K>i0b z*O2deTY|glL+`LM3+cbn@(>%6Z|>3Dx}pZEFdeenUvC$3pgdy<&>w$e%)0USuhssW z160BXDUyZ?*bk>_R`X+nRqSqa_E071^6CJwSi^rrG{vnIp|TLTQv2(+b*I1;X~NKQ zFJ-x@;OoA9V&X-(sa^ye-1K#VtboIi*g1Lw^$A^u4tU>_d(i_+m7`=k&m6r&06Q)+ zJoc%zYwO9_PaW!UBKXFuu&6ZM=#5h}We2C)No=k$yloC+VeKk7!42E?=W@-fv1}!F zH~uhAEwg};2+zgmhW@p}W(~BVJB!-i1aAgP_X1e)Dba=Sy(6HFP57Z0n}hJ|JDFD2 zA4qK=8Me;W5$k;W+Ra6ZzfikfSz+-6_6PrD8&y*#IHZ>f5S71f< zX)tQBJEV_kIXDl@U>{HMqlqc2SEadb#y(Fr!x{^IrcZTYW+xLmyA-Q8KSVRC>sn7u z6o5%j=C?RGiW@C)1W53$f1tO4aCR8|ig44s?gmtl$H&h4dl~uezT1sfLQ#Nf1`kc?&)-NV4b)s zOn!5fmTs>Ej3X44ulFSY6;DPY>87>Z) zlG-+@kSPQO1@5e2?gGG_FrtQZ>dwck3^<}HL-PRKP&Up4n$1SG>?ryW?a8_}TeP9U zTIFZRO(c)vCUcQs;?e~i4?;gNz)agvB}$i>vbi&}aW;Z0{p_RQQx$IIIHb625x4>5 zFY$COT$-T~%lwyco9NO*B^q94dSxS@*-|%M&1_^U^3ym&ZdUis$Qpio%r;z10I-_KO7Xc0Dmy@ z@aG8W>8#H)MjUHM*4`#2BC6&EF(iJ^FqG*agBS0=sMot3b6S}D_CP72r5xwF+>`@K z*vpH&5dQs5B%_@>3%hFcRV{+e)Bn7%A|%MSPrR_rVI)SEQIHC+n)AADJL~=5TTBq~ zwud24dOM~bwS~iXBo5jIrfZ8!O{xWN^*CnkUTr_A@<{esy9#7S4tTv}F_N?gQ0-2d zMj-^VrTT()9K-$!s1;Dr8wWF_SW)3ix=8U3-|9)LHAn*@Ks`Knj$;SM9a7H~7t=wb zk-@WSmCH#QRCNJjyq}_yR=wT5Q%mGq!W4?A6&&WYmS&IKw~ivJ_cEp<7kB>0%!zbn zlLCE3$83;(_KwrQ>T?`l8UdcCDUGpUDHWxr*>%SFv+H(G+EzOUFOAT0&Sn6}rB*fr z8{k(c!n}_z+2>O?#AP=%3XP^GtLYXPP~^f+CXmln`AYc-bLEw7IyXDx=aCK}PxFn= z-4c#z#@h@yfI+b}%cen1Eo{IK(WSJGHQbl%eh03^!kiQZNQR z5D@J8maT8~n}CWDWCv%ZtdN&y5cT-*2+)rh<%lpt*{GT+Fd1{DdWv=IUc*bkDH91T zG%%?T&uJ4RTs$0Pb>@uzU5NdJO(b5JcV_#C+C#vpB~-skm7f$zWX1e8SwqjdxWp0{ z(Y>CB6npb5=wX$82B~rbzaDM!6%#ECi*Woi^95#wT!#A}5^DGGzg%SdkrTJJUG>+y zozlA~(mew`*r$oOI~hsh!Vpf=`hU_}V^dP(SoN%8;mwymfUlWig>x@Ke}~j2Ndb#{ z#rT%WwjE-&^ZGW|-5@Y(UJQP@GBn?9e0bek~o`g@1)~<5u@Z>p7L;F`n zpacaU_erT{BrsYMaY8P++FolTvezNpfJ-qLyA>EA5Mt`lX|q8>(J#ebsT($i%34t} zVV}CG#2_&nxtW1hNtUXiH7`Zb%Rj(crc%|_wH%qB2+CeqmM&)>7k$7^Ci+6~{F(EMcBZ0>pV&dwM{shm z{X>E-n=8Ne8lggwc8ghx$3^%WhgD!<2j2_gym6)VAH-PsOO-BVs|g^ z@0IkP8H{=5{Q`w~P;}!4`jYK96^p`=lGyKUXe#+UQjGw0SuZWlbYIXTn=PLmOBNN3 zfjz!X&C&iZ()|cvo87E0kODvZqbq(gT9T5$j*g>^x3^nBay)2O@UGWjF8anMfzz0S z%wS5t-2;gkh-7py4Rj&NDH?)9@Us&8T0k^psc}uPbgS#JF*Ct8rW-0li`R;+${ifM z>Duz#jQ~l>xxO3tFFf=e`(MAbOuS+`nZ?8u4RHRi@6UW>yHwo${hk$iBRBn)ZcnkN z>eHg7P_%|S`vg55UqE|rS0{@6Xg+x)0DFFD;+xXp+wHM2GnsIJalLB)-@;>rDohN7i$zh#1B1V!;N$@66&TOU16;LmS@OH+? zgaVJ>4MXDN)s!H%T&XcmB5Z2K1#TeQXwC`)Pa<6qeUtMP$VLLB;NLDosyRUWKjyL; zQ;m@I_akS4$qGt@`nHspz@o(QrCWqo<}C3aj#!T0G($-&v4;g_q@gx0pla|v1)fh2 zP-m_SU`aM+7TJqd7mIDM^MV=>QR3A1#&Lam9G$^`TUMk9qbE&%!p1`@Cueo=msLsu z7eb+mdfk2-)s)TKXH=}Q7|rO=NX&KEZFmxTYd&=(!>>b^hq|3bxS&I+^^o^qBMYpsY(A;PhF;oyMt+11B`?uToByEw;pRHddxC#Qi`*8&^~X$vS?e z(~0|?lK2Bgkzs|2{+|_mWp2XROnGj<_MPD44K|53!m%&R7A<1Y*?bwQT7@zu=2g$Z zQ7NO=KrwQz>Q?EE%r5TVg6e_JO%zR02XpNUQoy`)-4s-;08(SAWWtV~Z*2C}sE#4( zB>eygUcy8hixaYRt>v@MGKv^rG@0tT0vFT{o(X<84Z39oJnsCr%e(bC+ymv4hbVJZ zxs9ID#a#H2b^0N@t}i8_Rd6U*>ivTTnoaUnP`GTo)$&%!ze=5xIZqX@il`&BaN*@6 z|Br^}mdS@aV0M^Hz94p`3QZ136jLdjP-Ha5o3|5xBz$Zc| z3sAT9qT&@Mr*4{UL&n_U9`&Z+(RAh^mN>+w8vjFKg)NKd76u9TFS1geUuT3|pcO18 zquf6u*HtYU=n@RmydEdi-#QVk(Zjk8f?f$jY~FKi!z+Jk=ivi)QDk1#xIJxvz$Yfr zTbAE$(WJ9%#+IAMA8oRI&{&0(mAK;L7#kOxF*~2C? zTtb|swcNnRP}Q99ZBO5hxrY=mqr*33`oLd9tP58KFYe`MguO|3(2^anaSHm|5(s+c z9O6A%E1Xj?+(K&5a&u@p09vrL0BK090sRkc73K)9=mcOx%9DnZjx3E0t(TDr@vkV8 zPVOejap7ZyLI0HH-uIqV`;3mWBX=tt?Zofe>(a%uQFK{@t`W|VTe s3j=RVTy&p7tMg~BR{P8y2scB>Qbx6{N;&27S$W3(Q(c09{!poUs8mlD*#H0l From 119cb604000baa3c76fbac6d549fa6c2501a20e0 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 18 Feb 2025 11:13:28 +0100 Subject: [PATCH 247/659] wip --- reproduction-models | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reproduction-models b/reproduction-models index f684425a7f..e57e2da781 160000 --- a/reproduction-models +++ b/reproduction-models @@ -1 +1 @@ -Subproject commit f684425a7fd16de224be74db0f8e416692e8a17b +Subproject commit e57e2da781d16cbc74aa604083b653aafed04a47 From 75fa6c6ebd7f606c2e6e7dccef01ee6356825b1d Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 18 Feb 2025 11:59:47 +0100 Subject: [PATCH 248/659] minor --- ccloud/fm-active-mq-source/fully-managed-active-mq-source.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/ccloud/fm-active-mq-source/fully-managed-active-mq-source.sh b/ccloud/fm-active-mq-source/fully-managed-active-mq-source.sh index 44cddf2cb2..8a01cb8402 100755 --- a/ccloud/fm-active-mq-source/fully-managed-active-mq-source.sh +++ b/ccloud/fm-active-mq-source/fully-managed-active-mq-source.sh @@ -69,8 +69,6 @@ playground connector create-or-update --connector $connector_name << EOF "activemq.password": "admin", "jms.destination.name": "DEV.QUEUE.1", "jms.destination.type": "queue", - "jms.destination.name": "DEV.QUEUE.1", - "jms.destination.type": "queue", "tasks.max" : "1" } EOF From cb5ec917298eaf58a825e38d41ca2142a1a3c7aa Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 18 Feb 2025 15:32:21 +0100 Subject: [PATCH 249/659] =?UTF-8?q?=F0=9F=91=BE=20Add=20Fully=20Managed=20?= =?UTF-8?q?ServiceNow=20Source=20V2=20Connector=20example=20#6304?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 2 +- ccloud/fm-servicenow-v2-source/README.md | 28 +++++ .../fully-managed-servicenow-v2-source.sh | 117 ++++++++++++++++++ ccloud/fm-servicenow-v2-source/stop.sh | 9 ++ docs/content-template.md | 1 + 5 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 ccloud/fm-servicenow-v2-source/README.md create mode 100755 ccloud/fm-servicenow-v2-source/fully-managed-servicenow-v2-source.sh create mode 100755 ccloud/fm-servicenow-v2-source/stop.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5a3e8ede55..3201f95593 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,7 +102,7 @@ jobs: "🚀 ccloud/fm-aws-kinesis-source ccloud/fm-aws-redshift-sink ccloud/fm-aws-sqs-source ccloud/fm-aws-lambda-sink ccloud/fm-azure-blob-storage-sink ccloud/fm-azure-blob-storage-source ccloud/fm-azure-cognitive-search-sink ccloud/fm-mongodb-atlas-source ccloud/fm-mongodb-atlas-sink ccloud/fm-salesforce-bulkapi-source ccloud/fm-salesforce-bulkapi-2-0-source ccloud/custom-connector-connect-aws-s3-sink", - "🚀 ccloud/fm-datadog-metrics-sink ccloud/fm-salesforce-bulkapi-2-0-sink ccloud/fm-salesforce-platform-events-source ccloud/fm-servicenow-source ccloud/fm-servicenow-sink ccloud/fm-aws-dynamodb-cdc-source ccloud/fm-datagen-source", + "🚀 ccloud/fm-datadog-metrics-sink ccloud/fm-salesforce-bulkapi-2-0-sink ccloud/fm-salesforce-platform-events-source ccloud/fm-servicenow-source ccloud/fm-servicenow-v2-source ccloud/fm-servicenow-sink ccloud/fm-aws-dynamodb-cdc-source ccloud/fm-datagen-source", "🚀 connect/connect-servicenow-sink connect/connect-servicenow-source connect/connect-datagen-source", "🚀 connect/connect-salesforce-bulkapi-sink connect/connect-salesforce-bulkapi-source connect/connect-salesforce-pushtopics-source connect/connect-salesforce-sobject-sink connect/connect-salesforce-cdc-source connect/connect-salesforce-platform-events-sink connect/connect-salesforce-platform-events-source", diff --git a/ccloud/fm-servicenow-v2-source/README.md b/ccloud/fm-servicenow-v2-source/README.md new file mode 100644 index 0000000000..0b1eef4e62 --- /dev/null +++ b/ccloud/fm-servicenow-v2-source/README.md @@ -0,0 +1,28 @@ +# Fully Managed ServiceNow Source V2 connector + + + +## Objective + +Quickly test [Fully Managed ServiceNow V2 Source](https://docs.confluent.io/cloud/current/connectors/cc-servicenow-source-v2.html) connector. + + + +## Register a test account + +Go to [ServiceNow developer portal](https://developer.servicenow.com) and register an account. +Click on `Manage`->`Instance` and register for a Vancouver instance. After some time (about one hour in my case) on the waiting list, you should receive an email with details of your test instance. + + +## How to run + +Simply run: + +``` +$ just use +``` + + +## Prerequisites + +See [here](https://kafka-docker-playground.io/#/how-to-use?id=%f0%9f%8c%a4%ef%b8%8f-confluent-cloud-examples) \ No newline at end of file diff --git a/ccloud/fm-servicenow-v2-source/fully-managed-servicenow-v2-source.sh b/ccloud/fm-servicenow-v2-source/fully-managed-servicenow-v2-source.sh new file mode 100755 index 0000000000..9d57f37beb --- /dev/null +++ b/ccloud/fm-servicenow-v2-source/fully-managed-servicenow-v2-source.sh @@ -0,0 +1,117 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + + + +function wait_for_end_of_hibernation () { + MAX_WAIT=600 + CUR_WAIT=0 + set +e + log "⌛ Waiting up to $MAX_WAIT seconds for end of hibernation to happen (it can take several minutes)" + curl -X POST "${SERVICENOW_URL}/api/now/table/incident" --user admin:"$SERVICENOW_PASSWORD" -H 'Accept: application/json' -H 'Content-Type: application/json' -H 'cache-control: no-cache' -d '{"short_description": "This is test"}' > /tmp/out.txt 2>&1 + while [[ $(cat /tmp/out.txt) =~ "Sign in to the site to wake your instance" ]] + do + sleep 10 + curl -X POST "${SERVICENOW_URL}/api/now/table/incident" --user admin:"$SERVICENOW_PASSWORD" -H 'Accept: application/json' -H 'Content-Type: application/json' -H 'cache-control: no-cache' -d '{"short_description": "This is test"}' > /tmp/out.txt 2>&1 + CUR_WAIT=$(( CUR_WAIT+10 )) + if [[ "$CUR_WAIT" -gt "$MAX_WAIT" ]]; then + echo -e "\nERROR: The logs still show 'Sign in to the site to wake your instance' after $MAX_WAIT seconds.\n" + exit 1 + fi + done + log "The instance is ready !" + set -e +} + +SERVICENOW_URL=${SERVICENOW_URL:-$1} +SERVICENOW_PASSWORD=${SERVICENOW_PASSWORD:-$2} + +if [ -z "$SERVICENOW_URL" ] +then + logerror "SERVICENOW_URL is not set. Export it as environment variable or pass it as argument" + exit 1 +fi + +if [[ "$SERVICENOW_URL" != */ ]] +then + logerror "SERVICENOW_URL does not end with "/" Example: https://dev12345.service-now.com/ " + exit 1 +fi + +if [ -z "$SERVICENOW_PASSWORD" ] +then + logerror "SERVICENOW_PASSWORD is not set. Export it as environment variable or pass it as argument" + exit 1 +fi + +if [ ! -z "$GITHUB_RUN_NUMBER" ] +then + # this is github actions + set +e + log "Waking up servicenow instance..." + docker run -e USERNAME="$SERVICENOW_DEVELOPER_USERNAME" -e PASSWORD="$SERVICENOW_DEVELOPER_PASSWORD" vdesabou/servicenowinstancewakeup:latest + set -e + wait_for_end_of_hibernation +fi + +bootstrap_ccloud_environment + +set +e +playground topic delete --topic topic-servicenow-incidents +set -e + +playground topic create --topic topic-servicenow-incidents + +connector_name="ServiceNowSourceV2_$USER" +set +e +playground connector delete --connector $connector_name > /dev/null 2>&1 +set -e + +TODAY=$(date -u '+%Y-%m-%d %H:%M:%S') + +log "Creating fully managed connector" +playground connector create-or-update --connector $connector_name << EOF +{ + "connector.class": "ServiceNowSourceV2", + "name": "$connector_name", + "kafka.auth.mode": "KAFKA_API_KEY", + "kafka.api.key": "$CLOUD_KEY", + "kafka.api.secret": "$CLOUD_SECRET", + "output.data.format": "AVRO", + "auth.type": "BASIC", + "servicenow.url": "$SERVICENOW_URL", + "connection.user": "admin", + "connection.password": "$SERVICENOW_PASSWORD", + "table1.name": "incident", + "table1.topic": "topic-servicenow-incidents", + "table1.start.timestamp": "$TODAY", + "table1.timestamp.field": "sys_updated_on", + "table1.display.value": "false", + "tasks.max" : "1" +} +EOF +wait_for_ccloud_connector_up $connector_name 180 + +sleep 10 + +log "Create one record to ServiceNow" +curl -X POST \ + "${SERVICENOW_URL}/api/now/table/incident" \ + --user admin:"$SERVICENOW_PASSWORD" \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'cache-control: no-cache' \ + -d '{"short_description": "This is test"}' + +sleep 5 + +log "Verify we have received the data in topic-servicenow-incidents topic" +playground topic consume --topic topic-servicenow-incidents --min-expected-messages 1 --timeout 60 + +log "Do you want to delete the fully managed connector $connector_name ?" +check_if_continue + +playground connector delete --connector $connector_name \ No newline at end of file diff --git a/ccloud/fm-servicenow-v2-source/stop.sh b/ccloud/fm-servicenow-v2-source/stop.sh new file mode 100755 index 0000000000..90ef041532 --- /dev/null +++ b/ccloud/fm-servicenow-v2-source/stop.sh @@ -0,0 +1,9 @@ +#!/bin/bash + + + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + + +maybe_delete_ccloud_environment diff --git a/docs/content-template.md b/docs/content-template.md index b2058f16de..d0e92d93e8 100644 --- a/docs/content-template.md +++ b/docs/content-template.md @@ -258,6 +258,7 @@ - [SalesForce SObject Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-salesforce-sobject-sink) :ccloud/fm-salesforce-sobject-sink: - [SalesForce PushTopics Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-salesforce-pushtopics-source) :ccloud/fm-salesforce-pushtopics-source: - [ServiceNow Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-servicenow-source) :ccloud/fm-servicenow-source: + - [ServiceNow Source V2](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-servicenow-v2-source) :ccloud/fm-servicenow-v2-source: - [ServiceNow Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-servicenow-sink) :ccloud/fm-servicenow-sink: - [SFTP Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-sftp-source) :ccloud/fm-sftp-source: - [SFTP Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/ccloud/fm-sftp-sink) :ccloud/fm-sftp-sink: From bd7fef807fbcabcb1af3cbd6ef329bd6edb768e3 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 19 Feb 2025 11:41:02 +0100 Subject: [PATCH 250/659] removed --- .github/workflows/ci-self-managed.yml | 215 -------------------------- 1 file changed, 215 deletions(-) delete mode 100644 .github/workflows/ci-self-managed.yml diff --git a/.github/workflows/ci-self-managed.yml b/.github/workflows/ci-self-managed.yml deleted file mode 100644 index 77c8e9547f..0000000000 --- a/.github/workflows/ci-self-managed.yml +++ /dev/null @@ -1,215 +0,0 @@ -name: CI Self-Managed - -on: - # push: - # branches: - # - master - - # schedule: - # - cron: '0 0 * * 0' # every week on sunday at 0 am - - workflow_dispatch: - inputs: - test_name: - description: 'test(s) to run (example connect/connect-jms-weblogic-sink connect/connect-http-sink)' - required: false - default: '' - -jobs: - start-runner: - name: Start Github self-hosted runner - runs-on: ubuntu-latest - steps: - - - name: Checkout code - uses: actions/checkout@v4 - with: - repository: vdesabou/kafka-docker-playground - fetch-depth: 0 - - - name: Decrypt secrets.tar - run: | - ./.github/scripts/decrypt_secret.sh - tar xvf secrets.tar - rm secrets.tar - mkdir -p $HOME/.aws - mv aws_credentials $HOME/.aws/credentials - chmod -R a+rw $HOME/.aws - mkdir -p $HOME/.confluent - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - env: - SECRETS_ENCRYPTION_PASSWORD: ${{ secrets.SECRETS_ENCRYPTION_PASSWORD }} - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME}} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD}} - - - name: Start EC2 instance github-actions-runner-vsaboulin - run: | - aws ec2 start-instances --instance-ids i-089ef31a75cb3f0e6 - - build: - runs-on: self-hosted - needs: start-runner # required to start the main job when the runner is read - name: ${{ matrix.tag }} ${{ matrix.test_list }} - strategy: - fail-fast: false - matrix: - tag: ["7.6.1"] - test_list : [ - "🚀 connect/connect-mapr-sink", - ] - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - repository: vdesabou/kafka-docker-playground - fetch-depth: 0 - - - name: Decrypt secrets.tar - run: | - ./.github/scripts/decrypt_secret.sh - tar xvf secrets.tar - rm secrets.tar - mkdir -p $HOME/.aws - mv aws_credentials_with_assuming_iam_role $HOME/.aws/credentials-with-assuming-iam-role - chmod -R a+rw $HOME/.aws - mkdir -p $HOME/.confluent - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - env: - SECRETS_ENCRYPTION_PASSWORD: ${{ secrets.SECRETS_ENCRYPTION_PASSWORD }} - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME}} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD}} - - - name: "Install confluent CLI" - run: | - curl -L --http1.1 https://cnfl.io/cli | sudo sh -s -- -b /usr/local/bin - export PATH=$PATH:/usr/local/bin - - - name: Build and Test - run: | - export PATH=$PATH:$GITHUB_WORKSPACE/scripts/cli - bash scripts/run-tests.sh "${{ matrix.test_list }}" "${{ matrix.tag }}" - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} - S3_PROVIDER_INTEGRATION_ID: ${{ secrets.S3_PROVIDER_INTEGRATION_ID}} - AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID}} - AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY}} - AWS_STS_ROLE_ARN: ${{ secrets.AWS_STS_ROLE_ARN}} - AZ_USER: ${{ secrets.AZ_USER}} - AZ_PASS: ${{ secrets.AZ_PASS}} - AZURE_SUBSCRIPTION_NAME: ${{ secrets.AZURE_SUBSCRIPTION_NAME}} - CONFLUENT_CLOUD_EMAIL: ${{ secrets.CONFLUENT_CLOUD_EMAIL}} - CONFLUENT_CLOUD_PASSWORD: ${{ secrets.CONFLUENT_CLOUD_PASSWORD}} - ENVIRONMENT: ${{ secrets.ENVIRONMENT}} - CLUSTER_NAME: ${{ secrets.CLUSTER_NAME}} - CLUSTER_REGION: ${{ secrets.CLUSTER_REGION}} - CLUSTER_CLOUD: ${{ secrets.CLUSTER_CLOUD}} - CLUSTER_CREDS: ${{ secrets.CLUSTER_CREDS}} - AWS_DATABRICKS_CLUSTER_NAME: ${{ secrets.AWS_DATABRICKS_CLUSTER_NAME}} - AWS_DATABRICKS_CLUSTER_REGION: ${{ secrets.AWS_DATABRICKS_CLUSTER_REGION}} - AWS_DATABRICKS_CLUSTER_CLOUD: ${{ secrets.AWS_DATABRICKS_CLUSTER_CLOUD}} - AWS_DATABRICKS_CLUSTER_CREDS: ${{ secrets.AWS_DATABRICKS_CLUSTER_CREDS}} - GCP_CLUSTER_NAME: ${{ secrets.GCP_CLUSTER_NAME}} - GCP_CLUSTER_REGION: ${{ secrets.GCP_CLUSTER_REGION}} - GCP_CLUSTER_CLOUD: ${{ secrets.GCP_CLUSTER_CLOUD}} - GCP_CLUSTER_CREDS: ${{ secrets.GCP_CLUSTER_CREDS}} - AZURE_CLUSTER_NAME: ${{ secrets.AZURE_CLUSTER_NAME}} - AZURE_CLUSTER_REGION: ${{ secrets.AZURE_CLUSTER_REGION}} - AZURE_CLUSTER_CLOUD: ${{ secrets.AZURE_CLUSTER_CLOUD}} - AZURE_CLUSTER_CREDS: ${{ secrets.AZURE_CLUSTER_CREDS}} - SCHEMA_REGISTRY_CREDS: ${{ secrets.SCHEMA_REGISTRY_CREDS}} - CONFLUENT_LICENSE: ${{ secrets.CONFLUENT_LICENSE}} - SALESFORCE_USERNAME: ${{ secrets.SALESFORCE_USERNAME}} - SALESFORCE_PASSWORD: ${{ secrets.SALESFORCE_PASSWORD}} - SALESFORCE_CONSUMER_KEY: ${{ secrets.SALESFORCE_CONSUMER_KEY}} - SALESFORCE_CONSUMER_PASSWORD: ${{ secrets.SALESFORCE_CONSUMER_PASSWORD}} - SALESFORCE_SECURITY_TOKEN: ${{ secrets.SALESFORCE_SECURITY_TOKEN}} - SALESFORCE_INSTANCE: ${{ secrets.SALESFORCE_INSTANCE}} - SALESFORCE_USERNAME_ACCOUNT2: ${{ secrets.SALESFORCE_USERNAME_ACCOUNT2}} - SALESFORCE_PASSWORD_ACCOUNT2: ${{ secrets.SALESFORCE_PASSWORD_ACCOUNT2}} - SALESFORCE_SECURITY_TOKEN_ACCOUNT2: ${{ secrets.SALESFORCE_SECURITY_TOKEN_ACCOUNT2}} - SALESFORCE_CONSUMER_KEY_ACCOUNT2: ${{ secrets.SALESFORCE_CONSUMER_KEY_ACCOUNT2}} - SALESFORCE_CONSUMER_PASSWORD_ACCOUNT2: ${{ secrets.SALESFORCE_CONSUMER_PASSWORD_ACCOUNT2}} - SALESFORCE_CONSUMER_KEY_WITH_JWT: ${{ secrets.SALESFORCE_CONSUMER_KEY_WITH_JWT}} - SALESFORCE_CONSUMER_PASSWORD_WITH_JWT: ${{ secrets.SALESFORCE_CONSUMER_PASSWORD_WITH_JWT}} - DD_API_KEY: ${{ secrets.DD_API_KEY}} - DD_APP_KEY: ${{ secrets.DD_APP_KEY}} - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME}} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD}} - JIRA_URL: ${{ secrets.JIRA_URL}} - JIRA_USERNAME: ${{ secrets.JIRA_USERNAME}} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN}} - MARKETO_ENDPOINT_URL: ${{ secrets.MARKETO_ENDPOINT_URL}} - MARKETO_CLIENT_ID: ${{ secrets.MARKETO_CLIENT_ID}} - MARKETO_CLIENT_SECRET: ${{ secrets.MARKETO_CLIENT_SECRET}} - PAGERDUTY_USER_EMAIL: ${{ secrets.PAGERDUTY_USER_EMAIL}} - PAGERDUTY_API_KEY: ${{ secrets.PAGERDUTY_API_KEY}} - PAGERDUTY_SERVICE_ID: ${{ secrets.PAGERDUTY_SERVICE_ID}} - CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_KEY: ${{ secrets.CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_KEY}} - CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_SECRET: ${{ secrets.CCLOUD_REST_PROXY_SECURITY_PLUGIN_API_SECRET}} - SERVICENOW_URL: ${{ secrets.SERVICENOW_URL}} - SERVICENOW_PASSWORD: ${{ secrets.SERVICENOW_PASSWORD}} - SERVICENOW_DEVELOPER_USERNAME: ${{ secrets.SERVICENOW_DEVELOPER_USERNAME}} - SERVICENOW_DEVELOPER_PASSWORD: ${{ secrets.SERVICENOW_DEVELOPER_PASSWORD}} - SNOWFLAKE_ACCOUNT_NAME: ${{ secrets.SNOWFLAKE_ACCOUNT_NAME}} - SNOWFLAKE_USERNAME: ${{ secrets.SNOWFLAKE_USERNAME}} - SNOWFLAKE_PASSWORD: ${{ secrets.SNOWFLAKE_PASSWORD}} - ZENDESK_URL: ${{ secrets.ZENDESK_URL}} - ZENDESK_USERNAME: ${{ secrets.ZENDESK_USERNAME}} - ZENDESK_PASSWORD: ${{ secrets.ZENDESK_PASSWORD}} - CONNECTOR_GITHUB_ACCESS_TOKEN: ${{ secrets.CONNECTOR_GITHUB_ACCESS_TOKEN}} - CI_GITHUB_TOKEN: ${{ secrets.CI_GITHUB_TOKEN}} - AUDIT_LOG_CLUSTER_BOOTSTRAP_SERVERS: ${{ secrets.AUDIT_LOG_CLUSTER_BOOTSTRAP_SERVERS}} - AUDIT_LOG_CLUSTER_API_KEY: ${{ secrets.AUDIT_LOG_CLUSTER_API_KEY}} - AUDIT_LOG_CLUSTER_API_SECRET: ${{ secrets.AUDIT_LOG_CLUSTER_API_SECRET}} - NGROK_AUTH_TOKEN: ${{ secrets.NGROK_CI_AUTH_TOKEN}} - DATABRICKS_AWS_BUCKET_NAME: ${{ secrets.DATABRICKS_AWS_BUCKET_NAME}} - DATABRICKS_AWS_BUCKET_REGION: ${{ secrets.DATABRICKS_AWS_BUCKET_REGION}} - DATABRICKS_AWS_STAGING_S3_ACCESS_KEY_ID: ${{ secrets.DATABRICKS_AWS_STAGING_S3_ACCESS_KEY_ID}} - DATABRICKS_AWS_STAGING_S3_SECRET_ACCESS_KEY: ${{ secrets.DATABRICKS_AWS_STAGING_S3_SECRET_ACCESS_KEY}} - DATABRICKS_SERVER_HOSTNAME: ${{ secrets.DATABRICKS_SERVER_HOSTNAME}} - DATABRICKS_HTTP_PATH: ${{ secrets.DATABRICKS_HTTP_PATH}} - DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN}} - ORACLE_CONTAINER_REGISTRY_USERNAME: ${{ secrets.ORACLE_CONTAINER_REGISTRY_USERNAME}} - ORACLE_CONTAINER_REGISTRY_PASSWORD: ${{ secrets.ORACLE_CONTAINER_REGISTRY_PASSWORD}} - GCP_KEYFILE_CONTENT: ${{ secrets.GCP_KEYFILE_CONTENT}} - GCP_PROJECT: ${{ secrets.GCP_PROJECT}} - HPE_MAPR_EMAIL: ${{ secrets.HPE_MAPR_EMAIL}} - HPE_MAPR_TOKEN: ${{ secrets.HPE_MAPR_TOKEN}} - MONGODB_ATLAS_HOST: ${{ secrets.MONGODB_ATLAS_HOST}} - MONGODB_ATLAS_USER: ${{ secrets.MONGODB_ATLAS_USER}} - MONGODB_ATLAS_PASSWORD: ${{ secrets.MONGODB_ATLAS_PASSWORD}} - - stop-runner: - name: Stop Github self-hosted runner - needs: - - start-runner # required to get output from the start-runner job - - build # required to wait when the main job is done - if: ${{ always() }} # required to stop the runner even if the error happened in the previous jobs - runs-on: ubuntu-latest - steps: - - - name: Checkout code - uses: actions/checkout@v4 - with: - repository: vdesabou/kafka-docker-playground - fetch-depth: 0 - - - name: Decrypt secrets.tar - run: | - ./.github/scripts/decrypt_secret.sh - tar xvf secrets.tar - rm secrets.tar - mkdir -p $HOME/.aws - mv aws_credentials_with_assuming_iam_role $HOME/.aws/credentials-with-assuming-iam-role - chmod -R a+rw $HOME/.aws - mkdir -p $HOME/.confluent - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - env: - SECRETS_ENCRYPTION_PASSWORD: ${{ secrets.SECRETS_ENCRYPTION_PASSWORD }} - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME}} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD}} - - - name: Stop EC2 instance github-actions-runner-vsaboulin - run: | - aws ec2 stop-instances --instance-ids i-089ef31a75cb3f0e6 From d1b7bb6ef8fc8ab0edc1925f5cae616fe4577b1b Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 19 Feb 2025 11:41:09 +0100 Subject: [PATCH 251/659] 7.9.0 --- .github/workflows/ci.yml | 6 +++--- .github/workflows/update-readme.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3201f95593..933ecc7f6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: strategy: fail-fast: false matrix: - tag: ["7.8.1"] + tag: ["7.9.0"] test_list : [ # requiring ngrok "🚀1️⃣ ccloud/fm-debezium-mysql-legacy-source ccloud/fm-debezium-postgresql-legacy-source ccloud/fm-debezium-mysql-v2-source ccloud/fm-debezium-sqlserver-legacy-source ccloud/fm-debezium-sqlserver-v2-source ccloud/fm-elasticsearch-sink ccloud/fm-jdbc-sqlserver-sink ccloud/fm-jdbc-sqlserver-source ccloud/fm-ibm-mq-source ccloud/fm-jdbc-mysql-source ccloud/fm-jdbc-postgresql-sink ccloud/fm-mqtt-source ccloud/fm-debezium-postgresql-v2-source ccloud/fm-jdbc-postgresql-source", @@ -329,7 +329,7 @@ jobs: strategy: fail-fast: false matrix: - tag: ["7.8.1"] + tag: ["7.9.0"] test_list : [ "🚀 ${{ github.event.inputs.test_name }}" ] @@ -607,7 +607,7 @@ jobs: - name: Update README run: | cd ./scripts/cli - ./playground update-readme --tags "7.8.1" + ./playground update-readme --tags "7.9.0" env: GH_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml index 513589936f..4eb0fdec7f 100644 --- a/.github/workflows/update-readme.yml +++ b/.github/workflows/update-readme.yml @@ -26,7 +26,7 @@ jobs: - name: Update README run: | cd ./scripts/cli - ./playground update-readme --tags "7.8.1" + ./playground update-readme --tags "7.9.0" env: GH_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} From 3156f2732efecb105011373c57d5b20c1b966045 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 19 Feb 2025 11:41:20 +0100 Subject: [PATCH 252/659] 7.9.0 --- scripts/cli/tag-list.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/cli/tag-list.txt b/scripts/cli/tag-list.txt index e9e91722d5..e3a3955ded 100644 --- a/scripts/cli/tag-list.txt +++ b/scripts/cli/tag-list.txt @@ -186,3 +186,4 @@ 7.7.2 7.8.0 7.8.1 +7.9.0 From f1f81689d9e5150b09d0fe0a5a709bc5ab3f98a7 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 19 Feb 2025 13:16:12 +0100 Subject: [PATCH 253/659] 7.9 --- scripts/cli/src/lib/utils_function.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index aee26f87f6..895f32e187 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -113,6 +113,11 @@ function version_gt() { function set_kafka_client_tag() { + if [[ $TAG_BASE = 7.9.* ]] + then + export KAFKA_CLIENT_TAG="3.9.0" + fi + if [[ $TAG_BASE = 7.8.* ]] then export KAFKA_CLIENT_TAG="3.8.0" From 3f3b3d3b2c769e64dd78bbcafae5f8e7b74cbff0 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 19 Feb 2025 13:45:31 +0100 Subject: [PATCH 254/659] fix --- connect/connect-http-source/http-source-no-auth.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connect/connect-http-source/http-source-no-auth.sh b/connect/connect-http-source/http-source-no-auth.sh index f5255ea2e5..1874522bb4 100755 --- a/connect/connect-http-source/http-source-no-auth.sh +++ b/connect/connect-http-source/http-source-no-auth.sh @@ -37,7 +37,7 @@ log "Send a message to HTTP server" curl -X PUT \ -H "Content-Type: application/json" \ --data '{"test":"value"}' \ - http://localhost:18080/api/messages | jq . + http://localhost:9006/api/messages sleep 2 From f47b2a8dbe61c63ba4e14e7265fe8e1d36ae0aee Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 19 Feb 2025 14:38:46 +0100 Subject: [PATCH 255/659] =?UTF-8?q?=F0=9F=91=BE=20Add=20fully=20managed=20?= =?UTF-8?q?examples=20for=20HTTP=20Source=20and=20HTTP=20Source=20v2=20wit?= =?UTF-8?q?hout=20any=20auth=20#6306?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fm-http-source/docker-compose.noauth.yml | 31 +++++ .../fully-managed-http-source.sh | 101 +++++++++++++++++ .../docker-compose.noauth.yml | 31 +++++ .../fully-managed-http-source-v2.sh | 107 ++++++++++++++++++ 4 files changed, 270 insertions(+) create mode 100644 ccloud/fm-http-source/docker-compose.noauth.yml create mode 100755 ccloud/fm-http-source/fully-managed-http-source.sh create mode 100644 ccloud/fm-http-v2-source/docker-compose.noauth.yml create mode 100755 ccloud/fm-http-v2-source/fully-managed-http-source-v2.sh diff --git a/ccloud/fm-http-source/docker-compose.noauth.yml b/ccloud/fm-http-source/docker-compose.noauth.yml new file mode 100644 index 0000000000..e0b48fd152 --- /dev/null +++ b/ccloud/fm-http-source/docker-compose.noauth.yml @@ -0,0 +1,31 @@ +--- +services: + + httpserver: + build: + context: ../../connect/connect-http-sink/httpserver + hostname: httpserver + container_name: httpserver + ports: + - "9006:9006" + + # https://ngrok.com/docs/using-ngrok-with/docker/ + ngrok: + image: ngrok/ngrok:latest + hostname: ngrok + container_name: ngrok + ports: + - 4040:4040 + restart: unless-stopped + links: + - httpserver + command: + - "start" + - "--all" + - "--log=stdout" + - "--config" + - "/etc/ngrok.yml" + volumes: + - ../../ccloud/fm-http-sink/ngrok.yml:/etc/ngrok.yml + environment: + NGROK_AUTHTOKEN: $NGROK_AUTH_TOKEN \ No newline at end of file diff --git a/ccloud/fm-http-source/fully-managed-http-source.sh b/ccloud/fm-http-source/fully-managed-http-source.sh new file mode 100755 index 0000000000..a55c7af57b --- /dev/null +++ b/ccloud/fm-http-source/fully-managed-http-source.sh @@ -0,0 +1,101 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +NGROK_AUTH_TOKEN=${NGROK_AUTH_TOKEN:-$1} + +display_ngrok_warning + +bootstrap_ccloud_environment + + + +docker compose -f docker-compose.noauth.yml build +docker compose -f docker-compose.noauth.yml down -v --remove-orphans +docker compose -f docker-compose.noauth.yml up -d --quiet-pull + +sleep 5 + +log "Waiting for ngrok to start" +while true +do + container_id=$(docker ps -q -f name=ngrok) + if [ -n "$container_id" ] + then + status=$(docker inspect --format '{{.State.Status}}' $container_id) + if [ "$status" = "running" ] + then + log "Getting ngrok hostname and port" + NGROK_URL=$(curl --silent http://127.0.0.1:4040/api/tunnels | jq -r '.tunnels[0].public_url') + NGROK_HOSTNAME=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 1) + NGROK_PORT=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 2) + + if ! [[ $NGROK_PORT =~ ^[0-9]+$ ]] + then + log "NGROK_PORT is not a valid number, keep retrying..." + continue + else + break + fi + fi + fi + log "Waiting for container ngrok to start..." + sleep 5 +done + +set +e +playground topic delete --topic http-source-topic-v1 +set -e + +log "Creating http-source-topic topic in Confluent Cloud"-v1 +set +e +playground topic create --topic http-source-topic-v1 +set -e + +connector_name="HttpSource_$USER" +set +e +playground connector delete --connector $connector_name > /dev/null 2>&1 +set -e + +log "Set webserver to reply with 200" +curl -X PUT -H "Content-Type: application/json" --data '{"errorCode": 200}' http://localhost:9006/set-response-error-code +# curl -X PUT -H "Content-Type: application/json" --data '{"delay": 2000}' http://localhost:9006/set-response-time +curl -X PUT -H "Content-Type: application/json" --data '{"store":{"book":[{"category":"reference","sold":false,"author":"Nigel Rees","title":"Sayings of the Century","price":8.95}],"bicycle":{"color":"red","price":19.95}}}' http://localhost:9006/set-response-body + +log "Creating fully managed connector" +playground connector create-or-update --connector $connector_name << EOF +{ + "connector.class": "HttpSource", + "name": "$connector_name", + "kafka.auth.mode": "KAFKA_API_KEY", + "kafka.api.key": "$CLOUD_KEY", + "kafka.api.secret": "$CLOUD_SECRET", + "topic.name.pattern": "http-source-topic",-v1 + "output.data.format": "AVRO", + "url": "http://$NGROK_HOSTNAME:$NGROK_PORT", + "entity.names": "messages", + "tasks.max" : "1", + "http.offset.mode": "SIMPLE_INCREMENTING", + "http.initial.offset": "0" +} +EOF +wait_for_ccloud_connector_up $connector_name 180 + +log "Send a message to HTTP server" +curl -X PUT \ + -H "Content-Type: application/json" \ + --data '{"test":"value"}' \ + http://localhost:9006/ + +sleep 2 + +log "Verify we have received the data in http-source-topic topic"-v1 +playground topic consume --topic http-source-topic --min-expected-messages 1 --timeout 60-v1 + + +log "Do you want to delete the fully managed connector $connector_name ?" +check_if_continue + +playground connector delete --connector $connector_name diff --git a/ccloud/fm-http-v2-source/docker-compose.noauth.yml b/ccloud/fm-http-v2-source/docker-compose.noauth.yml new file mode 100644 index 0000000000..e0b48fd152 --- /dev/null +++ b/ccloud/fm-http-v2-source/docker-compose.noauth.yml @@ -0,0 +1,31 @@ +--- +services: + + httpserver: + build: + context: ../../connect/connect-http-sink/httpserver + hostname: httpserver + container_name: httpserver + ports: + - "9006:9006" + + # https://ngrok.com/docs/using-ngrok-with/docker/ + ngrok: + image: ngrok/ngrok:latest + hostname: ngrok + container_name: ngrok + ports: + - 4040:4040 + restart: unless-stopped + links: + - httpserver + command: + - "start" + - "--all" + - "--log=stdout" + - "--config" + - "/etc/ngrok.yml" + volumes: + - ../../ccloud/fm-http-sink/ngrok.yml:/etc/ngrok.yml + environment: + NGROK_AUTHTOKEN: $NGROK_AUTH_TOKEN \ No newline at end of file diff --git a/ccloud/fm-http-v2-source/fully-managed-http-source-v2.sh b/ccloud/fm-http-v2-source/fully-managed-http-source-v2.sh new file mode 100755 index 0000000000..b1609622d9 --- /dev/null +++ b/ccloud/fm-http-v2-source/fully-managed-http-source-v2.sh @@ -0,0 +1,107 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +NGROK_AUTH_TOKEN=${NGROK_AUTH_TOKEN:-$1} + +display_ngrok_warning + +bootstrap_ccloud_environment + + +docker compose -f docker-compose.noauth.yml build +docker compose -f docker-compose.noauth.yml down -v --remove-orphans +docker compose -f docker-compose.noauth.yml up -d --quiet-pull + +sleep 5 + +log "Waiting for ngrok to start" +while true +do + container_id=$(docker ps -q -f name=ngrok) + if [ -n "$container_id" ] + then + status=$(docker inspect --format '{{.State.Status}}' $container_id) + if [ "$status" = "running" ] + then + log "Getting ngrok hostname and port" + NGROK_URL=$(curl --silent http://127.0.0.1:4040/api/tunnels | jq -r '.tunnels[0].public_url') + NGROK_HOSTNAME=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 1) + NGROK_PORT=$(echo $NGROK_URL | cut -d "/" -f3 | cut -d ":" -f 2) + + if ! [[ $NGROK_PORT =~ ^[0-9]+$ ]] + then + log "NGROK_PORT is not a valid number, keep retrying..." + continue + else + break + fi + fi + fi + log "Waiting for container ngrok to start..." + sleep 5 +done + +set +e +playground topic delete --topic http-source-topic-v2 +set -e + +log "Creating http-source-topic-v2 topic in Confluent Cloud" +set +e +playground topic create --topic http-source-topic-v2 +set -e + +connector_name="HttpSourceV2_$USER" +set +e +playground connector delete --connector $connector_name > /dev/null 2>&1 +set -e + +log "Set webserver to reply with 200" +curl -X PUT -H "Content-Type: application/json" --data '{"errorCode": 200}' http://localhost:9006/set-response-error-code +# curl -X PUT -H "Content-Type: application/json" --data '{"delay": 2000}' http://localhost:9006/set-response-time +curl -X PUT -H "Content-Type: application/json" --data '{"store":{"book":[{"category":"reference","sold":false,"author":"Nigel Rees","title":"Sayings of the Century","price":8.95}],"bicycle":{"color":"red","price":19.95}}}' http://localhost:9006/set-response-body + +log "Creating fully managed connector" +playground connector create-or-update --connector $connector_name << EOF +{ + "connector.class": "HttpSourceV2", + "name": "$connector_name", + "kafka.auth.mode": "KAFKA_API_KEY", + "kafka.api.key": "$CLOUD_KEY", + "kafka.api.secret": "$CLOUD_SECRET", + "output.data.format": "AVRO", + "http.api.base.url": "http://$NGROK_HOSTNAME:$NGROK_PORT", + "tasks.max" : "1", + + "http.api.base.url": "http://$NGROK_HOSTNAME:$NGROK_PORT", + "behavior.on.error": "FAIL", + "apis.num": "1", + "api1.http.api.path": "/", + "api1.topics": "http-source-topic-v2", + "api1.http.request.headers": "Content-Type: application/json", + "api1.test.api": "false", + "api1.http.offset.mode": "SIMPLE_INCREMENTING", + "api1.http.initial.offset": "0" +} +EOF +wait_for_ccloud_connector_up $connector_name 180 + +log "Send a message to HTTP server" +curl -X PUT \ + -H "Content-Type: application/json" \ + --data '{"test":"value"}' \ + http://localhost:9006/ + + +sleep 2 + +log "Verify we have received the data in http-source-topic-v2 topic" +playground topic consume --topic http-source-topic-v2 --min-expected-messages 1 --timeout 60 + + +log "Do you want to delete the fully managed connector $connector_name ?" +check_if_continue + +playground connector delete --connector $connector_name From e99bd1318fd0534e8b08dc540e638de135a5edd6 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 19 Feb 2025 14:38:53 +0100 Subject: [PATCH 256/659] minor --- connect/connect-http-source/http-source-no-auth.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/connect/connect-http-source/http-source-no-auth.sh b/connect/connect-http-source/http-source-no-auth.sh index 1874522bb4..d9a8049159 100755 --- a/connect/connect-http-source/http-source-no-auth.sh +++ b/connect/connect-http-source/http-source-no-auth.sh @@ -37,8 +37,7 @@ log "Send a message to HTTP server" curl -X PUT \ -H "Content-Type: application/json" \ --data '{"test":"value"}' \ - http://localhost:9006/api/messages - + http://localhost:9006/ sleep 2 From 017ed5b3b8de7eaabbfa99bc361387e0a00ac998 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 19 Feb 2025 14:39:06 +0100 Subject: [PATCH 257/659] minor --- scripts/cli/src/lib/utils_function.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 895f32e187..7dacfcc1ac 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -3983,8 +3983,9 @@ function check_arm64_support() { if [ $? = 0 ] then logerror "🖥️ This example is not working with ARM64 !" - log "It is highly recommended to use playground ec2 command (https://kafka-docker-playground.io/#/playground%20ec2) to run the example on ubuntu ec2 instance" - log "Do you want to start test anyway ?" + log "It is highly recommended to use 'playground ec2 command' (https://kafka-docker-playground.io/#/playground%20ec2) to run the example on ubuntu ec2 instance" + log "You can also use gitpod https://gitpod.io/#https://github.com/vdesabou/kafka-docker-playground" + log "Do you want to start the example anyway ?" check_if_continue return fi From 881d7872da252f6e72a6b0989cdde80a167c3e2c Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 20 Feb 2025 10:13:02 +0100 Subject: [PATCH 258/659] =?UTF-8?q?=F0=9F=91=BE=20Update=20default=20TAG?= =?UTF-8?q?=20to=207.9.0=20#6268?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 10 ++++++++-- scripts/utils.sh | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index c0d62d796b..0846149103 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8450,6 +8450,11 @@ function version_gt() { function set_kafka_client_tag() { + if [[ $TAG_BASE = 7.9.* ]] + then + export KAFKA_CLIENT_TAG="3.9.0" + fi + if [[ $TAG_BASE = 7.8.* ]] then export KAFKA_CLIENT_TAG="3.8.0" @@ -12245,8 +12250,9 @@ function check_arm64_support() { if [ $? = 0 ] then logerror "🖥️ This example is not working with ARM64 !" - log "It is highly recommended to use playground ec2 command (https://kafka-docker-playground.io/#/playground%20ec2) to run the example on ubuntu ec2 instance" - log "Do you want to start test anyway ?" + log "It is highly recommended to use 'playground ec2 command' (https://kafka-docker-playground.io/#/playground%20ec2) to run the example on ubuntu ec2 instance" + log "You can also use gitpod https://gitpod.io/#https://github.com/vdesabou/kafka-docker-playground" + log "Do you want to start the example anyway ?" check_if_continue return fi diff --git a/scripts/utils.sh b/scripts/utils.sh index 1d19260549..1e0afbdd96 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -33,7 +33,7 @@ fi if [ -z "$TAG" ] then # TAG is not set, use default: - export TAG=7.8.1 # default tag + export TAG=7.9.0 # default tag # to handle ubi8 images export TAG_BASE=$TAG if [ -z "$CP_KAFKA_IMAGE" ] From 6afb9c18bd185a17fac25ca5f93284f9e2e18bd0 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 20 Feb 2025 10:31:24 +0100 Subject: [PATCH 259/659] wip --- scripts/cli/completions.bash | 2 +- scripts/cli/confluent-hub-plugin-list.txt | 1 + scripts/cli/playground | 14 +++++++------- scripts/cli/playground.json | 4 ++-- scripts/cli/playground.yaml | 4 ++-- scripts/cli/src/bashly.yml | 4 ++-- scripts/cli/src/commands/ec2/create.sh | 2 +- scripts/cli/src/commands/ec2/open.sh | 4 ++-- 8 files changed, 18 insertions(+), 17 deletions(-) diff --git a/scripts/cli/completions.bash b/scripts/cli/completions.bash index b4f4624c04..cc298cabe2 100644 --- a/scripts/cli/completions.bash +++ b/scripts/cli/completions.bash @@ -1265,7 +1265,7 @@ _playground_completions() { ;; *'ec2 open'*) - while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--disable-sync-repro-folder --help --instance -h -i")" -- "$cur") + while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_playground_completions_filter "--enable-sync-repro-folder --help --instance -h -i")" -- "$cur") ;; *'history'*) diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index 47b2f8203e..8db99f7bc9 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -82,6 +82,7 @@ confluentinc/kafka-connect-mqtt confluentinc/kafka-connect-netezza confluentinc/kafka-connect-omnisci confluentinc/kafka-connect-oracle-cdc +confluentinc/kafka-connect-oracle-xstream-cdc-source confluentinc/kafka-connect-pagerduty confluentinc/kafka-connect-pinecone-sink confluentinc/kafka-connect-pivotal-gemfire diff --git a/scripts/cli/playground b/scripts/cli/playground index 0846149103..f63cffa6ce 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -6157,8 +6157,8 @@ playground_ec2_open_usage() { echo # :flag.usage - printf " %s\n" "$(magenta "--disable-sync-repro-folder")" - printf " 🚫 Disable sync reproduction-models folder between local and ec2 instance\n" + printf " %s\n" "$(magenta "--enable-sync-repro-folder")" + printf " 👉 Enable sync reproduction-models folder between local and ec2 instance\n" echo # :command.usage_fixed_flags @@ -25359,7 +25359,7 @@ playground_ec2_create_command() { log "👷 ec2 instance $name is created and accesible via SSH, it will be opened with visual studio code in 3 minutes..." log "🌀 cloud formation is still in progress (installing docker, etc...) and can be reverted after 10 minutes (i.e removing ec2 instance) in case of issue. You can check progress by checking log file output.log in root folder of ec2 instance" sleep 180 - playground ec2 open --instance "$instance" --disable-sync-repro-folder + playground ec2 open --instance "$instance" wait_for_ec2_cloudformation_to_be_completed "$name" @@ -25420,7 +25420,7 @@ playground_ec2_delete_command() { playground_ec2_open_command() { # src/commands/ec2/open.sh instance="${args[--instance]}" - disable_sync_repro_folder="${args[--disable-sync-repro-folder]}" + enable_sync_repro_folder="${args[--enable-sync-repro-folder]}" if [[ $(type code 2>&1) =~ "not found" ]] then @@ -25463,7 +25463,7 @@ playground_ec2_open_command() { playground ec2 allow-my-ip --instance "$instance" - if [[ ! -n "$disable_sync_repro_folder" ]] + if [[ -n "$enable_sync_repro_folder" ]] then instance="$(playground ec2 status --instance "$name" --all)" playground ec2 sync-repro-folder local-to-ec2 --instance "$instance" @@ -39648,10 +39648,10 @@ playground_ec2_open_parse_requirements() { ;; # :flag.case - --disable-sync-repro-folder) + --enable-sync-repro-folder) # :flag.case_no_arg - args['--disable-sync-repro-folder']=1 + args['--enable-sync-repro-folder']=1 shift ;; diff --git a/scripts/cli/playground.json b/scripts/cli/playground.json index 20297d02a9..8ab379f1f3 100644 --- a/scripts/cli/playground.json +++ b/scripts/cli/playground.json @@ -3038,10 +3038,10 @@ }, { "names": [ - "--disable-sync-repro-folder" + "--enable-sync-repro-folder" ], "argument": "", - "description": "🚫 Disable sync reproduction-models folder between local and ec2 instance\n" + "description": "👉 Enable sync reproduction-models folder between local and ec2 instance\n" } ] }, diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index 099e3b1464..83ec77633a 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -3203,10 +3203,10 @@ subcommands: 🎓 Tip: If not specified, the command will apply to all ec2 instances - names: - - --disable-sync-repro-folder + - --enable-sync-repro-folder argument: "" description: | - 🚫 Disable sync reproduction-models folder between local and ec2 instance + 👉 Enable sync reproduction-models folder between local and ec2 instance - name: list description: | diff --git a/scripts/cli/src/bashly.yml b/scripts/cli/src/bashly.yml index f10d20ac8e..7d25195165 100644 --- a/scripts/cli/src/bashly.yml +++ b/scripts/cli/src/bashly.yml @@ -3649,10 +3649,10 @@ commands: 🖥️ ec2 instance (need to use completion to get all required details) 🎓 Tip: If not specified, the command will apply to all ec2 instances - - long: --disable-sync-repro-folder + - long: --enable-sync-repro-folder required: false help: |- - 🚫 Disable sync reproduction-models folder between local and ec2 instance + 👉 Enable sync reproduction-models folder between local and ec2 instance - name: allow-my-ip private: true diff --git a/scripts/cli/src/commands/ec2/create.sh b/scripts/cli/src/commands/ec2/create.sh index 465167da74..3eef6b5734 100644 --- a/scripts/cli/src/commands/ec2/create.sh +++ b/scripts/cli/src/commands/ec2/create.sh @@ -77,7 +77,7 @@ fi log "👷 ec2 instance $name is created and accesible via SSH, it will be opened with visual studio code in 3 minutes..." log "🌀 cloud formation is still in progress (installing docker, etc...) and can be reverted after 10 minutes (i.e removing ec2 instance) in case of issue. You can check progress by checking log file output.log in root folder of ec2 instance" sleep 180 -playground ec2 open --instance "$instance" --disable-sync-repro-folder +playground ec2 open --instance "$instance" wait_for_ec2_cloudformation_to_be_completed "$name" diff --git a/scripts/cli/src/commands/ec2/open.sh b/scripts/cli/src/commands/ec2/open.sh index b43bc75098..eebe36373c 100644 --- a/scripts/cli/src/commands/ec2/open.sh +++ b/scripts/cli/src/commands/ec2/open.sh @@ -1,5 +1,5 @@ instance="${args[--instance]}" -disable_sync_repro_folder="${args[--disable-sync-repro-folder]}" +enable_sync_repro_folder="${args[--enable-sync-repro-folder]}" if [[ $(type code 2>&1) =~ "not found" ]] then @@ -42,7 +42,7 @@ do playground ec2 allow-my-ip --instance "$instance" - if [[ ! -n "$disable_sync_repro_folder" ]] + if [[ -n "$enable_sync_repro_folder" ]] then instance="$(playground ec2 status --instance "$name" --all)" playground ec2 sync-repro-folder local-to-ec2 --instance "$instance" From dcde9bc86523e1d1e500666e05e1b7910223e062 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 20 Feb 2025 10:54:57 +0100 Subject: [PATCH 260/659] typo --- ccloud/fm-http-source/fully-managed-http-source.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ccloud/fm-http-source/fully-managed-http-source.sh b/ccloud/fm-http-source/fully-managed-http-source.sh index a55c7af57b..d7bb17ab56 100755 --- a/ccloud/fm-http-source/fully-managed-http-source.sh +++ b/ccloud/fm-http-source/fully-managed-http-source.sh @@ -46,12 +46,12 @@ do done set +e -playground topic delete --topic http-source-topic-v1 +playground topic delete --topic http-source-v1-topic set -e -log "Creating http-source-topic topic in Confluent Cloud"-v1 +log "Creating http-source-v1-topic topic in Confluent Cloud" set +e -playground topic create --topic http-source-topic-v1 +playground topic create --topic http-source-v1-topic set -e connector_name="HttpSource_$USER" @@ -72,7 +72,7 @@ playground connector create-or-update --connector $connector_name << EOF "kafka.auth.mode": "KAFKA_API_KEY", "kafka.api.key": "$CLOUD_KEY", "kafka.api.secret": "$CLOUD_SECRET", - "topic.name.pattern": "http-source-topic",-v1 + "topic.name.pattern": "http-source-v1-topic", "output.data.format": "AVRO", "url": "http://$NGROK_HOSTNAME:$NGROK_PORT", "entity.names": "messages", @@ -91,8 +91,8 @@ curl -X PUT \ sleep 2 -log "Verify we have received the data in http-source-topic topic"-v1 -playground topic consume --topic http-source-topic --min-expected-messages 1 --timeout 60-v1 +log "Verify we have received the data in http-source-v1-topic topic" +playground topic consume --topic http-source-v1-topic --min-expected-messages 1 --timeout 60 log "Do you want to delete the fully managed connector $connector_name ?" From ad7c869ec0b63f0f7462436fd2d644cc5d2a6d01 Mon Sep 17 00:00:00 2001 From: LGouellec Date: Thu, 20 Feb 2025 15:33:13 -0800 Subject: [PATCH 261/659] =?UTF-8?q?=F0=9F=92=A5=20-=20DataDog=20Logs=20Sin?= =?UTF-8?q?k=20Connector?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- connect/connect-datadog-logs-sink/README.md | 85 +++++++++++++++ .../connect-datadog-logs-sink/api_key_dd.png | Bin 0 -> 251895 bytes .../connect-datadog-logs-sink/app_key_dd.png | Bin 0 -> 235538 bytes .../datadog-logs-sink.sh | 74 +++++++++++++ connect/connect-datadog-logs-sink/dd_logs.png | Bin 0 -> 292674 bytes .../docker-compose.plaintext.yml | 5 + connect/connect-datadog-logs-sink/stop.sh | 8 ++ kafka-docker-playground.sln | 62 +++++++++++ scripts/cli/confluent-hub-plugin-list.txt | 1 + scripts/cli/confluent-kafka-region-list.txt | 99 ------------------ scripts/cli/tag-list.txt | 1 + 12 files changed, 239 insertions(+), 100 deletions(-) create mode 100644 connect/connect-datadog-logs-sink/README.md create mode 100644 connect/connect-datadog-logs-sink/api_key_dd.png create mode 100644 connect/connect-datadog-logs-sink/app_key_dd.png create mode 100755 connect/connect-datadog-logs-sink/datadog-logs-sink.sh create mode 100644 connect/connect-datadog-logs-sink/dd_logs.png create mode 100644 connect/connect-datadog-logs-sink/docker-compose.plaintext.yml create mode 100755 connect/connect-datadog-logs-sink/stop.sh create mode 100644 kafka-docker-playground.sln diff --git a/.gitignore b/.gitignore index 5cdd8df5b3..7c4a67ae4a 100644 --- a/.gitignore +++ b/.gitignore @@ -76,4 +76,6 @@ playground_config.ini .connector_config hsperfdata_appuser *.lck -reproduction-models \ No newline at end of file +reproduction-models +**/bin/ +**/obj \ No newline at end of file diff --git a/connect/connect-datadog-logs-sink/README.md b/connect/connect-datadog-logs-sink/README.md new file mode 100644 index 0000000000..c1ab50aaa0 --- /dev/null +++ b/connect/connect-datadog-logs-sink/README.md @@ -0,0 +1,85 @@ +# Datadog Logs Sink connector + + +## Objective + +Quickly test [Datadog Logs Sink](https://www.confluent.io/hub/datadog/kafka-connect-logs) connector. + +## Prerequisites + +Register for a [Datadog trial](https://app.datadoghq.com) if you don't already have an account (you can convert it to *Free plan* after the trial expires). + +Create an API key (`DD_API_KEY`) and an Application key (`DD_APP_KEY`): + +![Datadog API Key](api_key_dd.png) +![Datadog APP Key](app_key_dd.png) + +## How to run + +Export DataDog Environment variables + +Example : +``` +$ export DD_API_KEY="4a**********0" +$ export DD_APP_KEY="c43**************67" +$ export DD_SITE="us5.datadoghq.com" +``` + +Simply run: + +``` +$ just use command and search for datadog-logs-sink-sink in this folder + +``` + +## Details of what the script is doing + +Sending messages to topic datadog-logs-topic: + +```bash +$ docker exec -i connect kafka-console-producer --bootstrap-server broker:9092 --topic datadog-logs-topic << EOF +This is a log line +EOF +``` + +Creating Datadog metrics sink connector: + +```bash +$ curl -X PUT \ + -H "Content-Type: application/json" \ + --data '{ + "connector.class": "com.datadoghq.connect.logs.DatadogLogsSinkConnector", + "tasks.max": "1", + "key.converter":"org.apache.kafka.connect.storage.StringConverter", + "value.converter":"org.apache.kafka.connect.storage.StringConverter", + "confluent.topic.bootstrap.servers": "broker:9092", + "confluent.topic.replication.factor":1, + "datadog.api_key": "$DD_API_KEY", + "datadog.site": "$DD_SITE", + "reporter.bootstrap.servers": "broker:9092", + "reporter.error.topic.name": "error-responses", + "reporter.error.topic.replication.factor": 1, + "reporter.result.topic.name": "success-responses", + "reporter.result.topic.replication.factor": 1, + "behavior.on.error": "fail", + "topics": "datadog-logs-topic" + }' \ + http://localhost:8083/connectors/datadog-metrics-sink/config | jq . +``` + +Make sure `This is a log line` is present in Datadog +``` +$ curl -s -X POST "https://api.$DD_SITE/api/v2/logs/events/search" \ +-H "Content-Type: application/json" \ +-H "DD-API-KEY: $DD_API_KEY" \ +-H "DD-APPLICATION-KEY: $DD_APP_KEY" \ +--data-raw '{ + "page": { + "limit":1 + }, + "sort":"-timestamp" +}' +``` + +Check the data is in Datadog: +![Datadog logs](dd_logs.png) \ No newline at end of file diff --git a/connect/connect-datadog-logs-sink/api_key_dd.png b/connect/connect-datadog-logs-sink/api_key_dd.png new file mode 100644 index 0000000000000000000000000000000000000000..75fee22043b990a14ce16a652f93e28b908d61db GIT binary patch literal 251895 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 WHuL;|DYypTT`@4ZSbo9f?*9UU?WNNI literal 0 HcmV?d00001 diff --git a/connect/connect-datadog-logs-sink/app_key_dd.png b/connect/connect-datadog-logs-sink/app_key_dd.png new file mode 100644 index 0000000000000000000000000000000000000000..d5bbb54249cc8fd97261a0040dfb2535786b7103 GIT binary patch literal 235538 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%0Ag*z^vp~P&>S|y=}>7FpbR){ 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

IimLcRvt`fS)~!++cL5 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 Ob5;MwrNRq$AO9adXap$$ literal 0 HcmV?d00001 diff --git a/connect/connect-datadog-logs-sink/datadog-logs-sink.sh b/connect/connect-datadog-logs-sink/datadog-logs-sink.sh new file mode 100755 index 0000000000..d8f9169c47 --- /dev/null +++ b/connect/connect-datadog-logs-sink/datadog-logs-sink.sh @@ -0,0 +1,74 @@ +#!/bin/bash +set -e + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +DD_API_KEY=${DD_API_KEY:-$1} +DD_SITE=${DD_SITE:-$2} +DD_APP_KEY=${DD_APP_KEY:-$3} + +if [ -z "$DD_API_KEY" ] +then + logerror "DD_API_KEY is not set. Export it as environment variable or pass it as argument" + exit 1 +fi + +if [ -z "$DD_SITE" ] +then + logerror "DD_SITE is not set. Export it as environment variable or pass it as argument" + exit 1 +fi + +if [ -z "$DD_APP_KEY" ] +then + logerror "DD_APP_KEY is not set. Export it as environment variable or pass it as argument" + exit 1 +fi + + +PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} +playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" + +log "Sending messages to topic datadog-logs-topic" +TIMESTAMP=`date +%s` +playground topic produce -t datadog-logs-topic --nb-messages 1 --value="This is a log line" + +log "Creating Datadog logs sink connector" +playground connector create-or-update --connector datadog-logs-sink << EOF +{ + "connector.class": "com.datadoghq.connect.logs.DatadogLogsSinkConnector", + "tasks.max": "1", + "key.converter":"org.apache.kafka.connect.storage.StringConverter", + "value.converter":"org.apache.kafka.connect.storage.StringConverter", + "confluent.topic.bootstrap.servers": "broker:9092", + "confluent.topic.replication.factor":1, + "datadog.api_key": "$DD_API_KEY", + "datadog.site": "$DD_SITE", + "reporter.bootstrap.servers": "broker:9092", + "reporter.error.topic.name": "error-responses", + "reporter.error.topic.replication.factor": 1, + "reporter.result.topic.name": "success-responses", + "reporter.result.topic.replication.factor": 1, + "behavior.on.error": "fail", + "topics": "datadog-logs-topic" +} +EOF + +sleep 20 + + +log "Make sure logs is present in Datadog" + +curl -s -X POST "https://api.$DD_SITE/api/v2/logs/events/search" \ +-H "Content-Type: application/json" \ +-H "DD-API-KEY: $DD_API_KEY" \ +-H "DD-APPLICATION-KEY: $DD_APP_KEY" \ +--data-raw '{ + "page": { + "limit":1 + }, + "sort":"-timestamp" +}' > /tmp/result.log + +grep "This is a log line" /tmp/result.log diff --git a/connect/connect-datadog-logs-sink/dd_logs.png b/connect/connect-datadog-logs-sink/dd_logs.png new file mode 100644 index 0000000000000000000000000000000000000000..28913f54b5c1c5858f7e16e6bdf413c8500d8be6 GIT binary patch literal 292674 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

m?IcSkw;@CmHWS;_Q!}Yo?>>K8f3qt`u*|! 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�eE@DtQ&zx3t1|t)`oI0R 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

*)VN+>?fH|?P&}|KH4(%tP0@zN1w6Bmny;Vn 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

Mx9>`B7B7vI84Q9A2YO})oj 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/dev/null && pwd )" +source ${DIR}/../../scripts/utils.sh + +stop_all "$DIR" \ No newline at end of file diff --git a/kafka-docker-playground.sln b/kafka-docker-playground.sln new file mode 100644 index 0000000000..00d602f65b --- /dev/null +++ b/kafka-docker-playground.sln @@ -0,0 +1,62 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "other", "other", "{A36FAAB1-3B70-FACF-6B1E-E7138A3CFC44}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ccloud", "ccloud", "{23A3CAC0-821E-7AD0-08BD-CA0EE349EAFD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNet2.2", "other\client-dotnet\DotNet2.2.csproj", "{625BE235-268A-2C24-CBAB-2179484E8F6A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNet3.1", "other\client-dotnet\DotNet3.1.csproj", "{1D28699F-2914-0C47-88FD-02E4E032105F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CCloud2.2", "ccloud\client-dotnet\CCloud2.2.csproj", "{CC0B8A5C-26CF-D9A8-097D-D9817C56F10E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CCloud3.1", "ccloud\client-dotnet\CCloud3.1.csproj", "{E71428FB-D2F1-7DBE-3776-43AC8C44B9E1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "monitoring-demo", "monitoring-demo", "{4828A052-A836-CE0D-A6B8-54B2D4A2BDD4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Monitoring", "other\monitoring-demo\client-dotnet\Monitoring.csproj", "{D91C8015-30A1-65B8-CCA6-B575106E5070}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {625BE235-268A-2C24-CBAB-2179484E8F6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {625BE235-268A-2C24-CBAB-2179484E8F6A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {625BE235-268A-2C24-CBAB-2179484E8F6A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {625BE235-268A-2C24-CBAB-2179484E8F6A}.Release|Any CPU.Build.0 = Release|Any CPU + {1D28699F-2914-0C47-88FD-02E4E032105F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1D28699F-2914-0C47-88FD-02E4E032105F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1D28699F-2914-0C47-88FD-02E4E032105F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1D28699F-2914-0C47-88FD-02E4E032105F}.Release|Any CPU.Build.0 = Release|Any CPU + {CC0B8A5C-26CF-D9A8-097D-D9817C56F10E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CC0B8A5C-26CF-D9A8-097D-D9817C56F10E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CC0B8A5C-26CF-D9A8-097D-D9817C56F10E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CC0B8A5C-26CF-D9A8-097D-D9817C56F10E}.Release|Any CPU.Build.0 = Release|Any CPU + {E71428FB-D2F1-7DBE-3776-43AC8C44B9E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E71428FB-D2F1-7DBE-3776-43AC8C44B9E1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E71428FB-D2F1-7DBE-3776-43AC8C44B9E1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E71428FB-D2F1-7DBE-3776-43AC8C44B9E1}.Release|Any CPU.Build.0 = Release|Any CPU + {D91C8015-30A1-65B8-CCA6-B575106E5070}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D91C8015-30A1-65B8-CCA6-B575106E5070}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D91C8015-30A1-65B8-CCA6-B575106E5070}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D91C8015-30A1-65B8-CCA6-B575106E5070}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {625BE235-268A-2C24-CBAB-2179484E8F6A} = {A36FAAB1-3B70-FACF-6B1E-E7138A3CFC44} + {1D28699F-2914-0C47-88FD-02E4E032105F} = {A36FAAB1-3B70-FACF-6B1E-E7138A3CFC44} + {CC0B8A5C-26CF-D9A8-097D-D9817C56F10E} = {23A3CAC0-821E-7AD0-08BD-CA0EE349EAFD} + {E71428FB-D2F1-7DBE-3776-43AC8C44B9E1} = {23A3CAC0-821E-7AD0-08BD-CA0EE349EAFD} + {4828A052-A836-CE0D-A6B8-54B2D4A2BDD4} = {A36FAAB1-3B70-FACF-6B1E-E7138A3CFC44} + {D91C8015-30A1-65B8-CCA6-B575106E5070} = {4828A052-A836-CE0D-A6B8-54B2D4A2BDD4} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D11B5B17-01D3-4289-9564-52BB9178AEC2} + EndGlobalSection +EndGlobal diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index 47b2f8203e..8db99f7bc9 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -82,6 +82,7 @@ confluentinc/kafka-connect-mqtt confluentinc/kafka-connect-netezza confluentinc/kafka-connect-omnisci confluentinc/kafka-connect-oracle-cdc +confluentinc/kafka-connect-oracle-xstream-cdc-source confluentinc/kafka-connect-pagerduty confluentinc/kafka-connect-pinecone-sink confluentinc/kafka-connect-pivotal-gemfire diff --git a/scripts/cli/confluent-kafka-region-list.txt b/scripts/cli/confluent-kafka-region-list.txt index 518e686afa..e69de29bb2 100644 --- a/scripts/cli/confluent-kafka-region-list.txt +++ b/scripts/cli/confluent-kafka-region-list.txt @@ -1,99 +0,0 @@ -Name/Region -Bahrain(me-south-1)/me-south-1 -Belgium(europe-west1)/europe-west1 -Calgary(ca-west-1)/ca-west-1 -Canada(ca-central-1)/ca-central-1 -CapeTown(af-south-1)/af-south-1 -Dallas(us-south1)/us-south1 -Dammam(me-central2)/me-central2 -Delhi(asia-south2)/asia-south2 -Doha(me-central1)/me-central1 -Doha(qatarcentral)/qatarcentral -Dubai(uaenorth)/uaenorth -Finland(europe-north1)/europe-north1 -Frankfurt(eu-central-1)/eu-central-1 -Frankfurt(europe-west3)/europe-west3 -Frankfurt(germanywestcentral)/germanywestcentral -Gävle(swedencentral)/swedencentral -HongKong(ap-east-1)/ap-east-1 -HongKong(asia-east2)/asia-east2 -HongKong(eastasia)/eastasia -Hyderabad(ap-south-2)/ap-south-2 -Iowa(centralus)/centralus -Iowa(us-central1)/us-central1 -Ireland(eu-west-1)/eu-west-1 -Ireland(northeurope)/northeurope -Jakarta(ap-southeast-3)/ap-southeast-3 -Jakarta(asia-southeast2)/asia-southeast2 -Johannesburg/southafricanorth -(southafricanorth)/ -LasVegas(us-west4)/us-west4 -London(eu-west-2)/eu-west-2 -London(europe-west2)/europe-west2 -London(uksouth)/uksouth -LosAngeles(us-west2)/us-west2 -Madrid(europe-southwest1)/europe-southwest1 -Melbourne(ap-southeast-4)/ap-southeast-4 -Melbourne/australia-southeast2 -(australia-southeast2)/ -MexicoCentral(mexicocentral)/mexicocentral -Milan(eu-south-1)/eu-south-1 -Milan(europe-west8)/europe-west8 -Milan(italynorth)/italynorth -Montreal/northamerica-northeast1 -(northamerica-northeast1)/ -Mumbai(ap-south-1)/ap-south-1 -Mumbai(asia-south1)/asia-south1 -N.Virginia(us-east-1)/us-east-1 -N.Virginia(us-east4)/us-east4 -Netherlands(europe-west4)/europe-west4 -Netherlands(westeurope)/westeurope -NewSouthWales/australiaeast -(australiaeast)/ -Ohio(us-east-2)/us-east-2 -Oregon(us-west-2)/us-west-2 -Oregon(us-west1)/us-west1 -Osaka(ap-northeast-3)/ap-northeast-3 -Osaka(asia-northeast2)/asia-northeast2 -Oslo(norwayeast)/norwayeast -Paris(eu-west-3)/eu-west-3 -Paris(europe-west9)/europe-west9 -Paris(francecentral)/francecentral -Phoenix(westus3)/westus3 -Pune(centralindia)/centralindia -S.Carolina(us-east1)/us-east1 -SaltLakeCity(us-west3)/us-west3 -Santiago(southamerica-west1)/southamerica-west1 -SaoPaulo(southamerica-east1)/southamerica-east1 -SaoPaulostate(brazilsouth)/brazilsouth -Seoul(ap-northeast-2)/ap-northeast-2 -Seoul(asia-northeast3)/asia-northeast3 -Seoul(koreacentral)/koreacentral -Singapore(ap-southeast-1)/ap-southeast-1 -Singapore(asia-southeast1)/asia-southeast1 -Singapore(southeastasia)/southeastasia -Spain(eu-south-2)/eu-south-2 -Spain(spaincentral)/spaincentral -Stockholm(eu-north-1)/eu-north-1 -Sydney(ap-southeast-2)/ap-southeast-2 -Sydney(australia-southeast1)/australia-southeast1 -SãoPaulo(sa-east-1)/sa-east-1 -Taiwan(asia-east1)/asia-east1 -TelAviv(il-central-1)/il-central-1 -TelAviv(me-west1)/me-west1 -Texas(southcentralus)/southcentralus -Tokyo(ap-northeast-1)/ap-northeast-1 -Tokyo(asia-northeast1)/asia-northeast1 -Tokyo(japaneast)/japaneast -Toronto(canadacentral)/canadacentral -Toronto/northamerica-northeast2 -(northamerica-northeast2)/ -Turin(europe-west12)/europe-west12 -UAE(me-central-1)/me-central-1 -Virginia(eastus)/eastus -Virginia(eastus2)/eastus2 -Warsaw(europe-central2)/europe-central2 -Washington(westus2)/westus2 -Zurich(eu-central-2)/eu-central-2 -Zurich(europe-west6)/europe-west6 -Zurich(switzerlandnorth)/switzerlandnorth diff --git a/scripts/cli/tag-list.txt b/scripts/cli/tag-list.txt index e9e91722d5..e3a3955ded 100644 --- a/scripts/cli/tag-list.txt +++ b/scripts/cli/tag-list.txt @@ -186,3 +186,4 @@ 7.7.2 7.8.0 7.8.1 +7.9.0 From d6c72594f2f1571edfb081f33f08476b993a1273 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 3 Mar 2025 12:16:38 +0100 Subject: [PATCH 262/659] wip --- scripts/cli/confluent-hub-plugin-list.txt | 3 +-- scripts/cli/confluent-kafka-region-list.txt | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index 8db99f7bc9..2c6a862e9a 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -34,7 +34,6 @@ confluentinc/kafka-connect-aws-lambda confluentinc/kafka-connect-aws-redshift confluentinc/kafka-connect-azure-blob-storage confluentinc/kafka-connect-azure-blob-storage-source -confluentinc/kafka-connect-azure-data-lake-gen1-storage confluentinc/kafka-connect-azure-data-lake-gen2-storage confluentinc/kafka-connect-azure-event-hubs confluentinc/kafka-connect-azure-functions @@ -198,7 +197,6 @@ singlestore/singlestore-kafka-connector snowflakeinc/snowflake-kafka-connector splunk/kafka-connect-splunk spoudinc/spoud-agoora -sqdata/sqdata-connector startree/startree-native-integration streaming-dev-lab/secured-flow streamsendio/file-chunk-sink @@ -211,6 +209,7 @@ tabular/iceberg-kafka-connect thomaskwscott/kafka-connect-shell-sink thomaskwscott/kafka-connect-shell-source timeplus/kafka-timeplus-connector-sink +vectara/kafka-connect-vectara vertica/vertica-analytics-platform waterstreamsrl/waterstream-kafka-mqtt wepay/kafka-connect-bigquery diff --git a/scripts/cli/confluent-kafka-region-list.txt b/scripts/cli/confluent-kafka-region-list.txt index 518e686afa..281f100a85 100644 --- a/scripts/cli/confluent-kafka-region-list.txt +++ b/scripts/cli/confluent-kafka-region-list.txt @@ -25,6 +25,7 @@ Ireland(eu-west-1)/eu-west-1 Ireland(northeurope)/northeurope Jakarta(ap-southeast-3)/ap-southeast-3 Jakarta(asia-southeast2)/asia-southeast2 +JioIndiaWest(jioindiawest)/jioindiawest Johannesburg/southafricanorth (southafricanorth)/ LasVegas(us-west4)/us-west4 @@ -50,6 +51,8 @@ Netherlands(europe-west4)/europe-west4 Netherlands(westeurope)/westeurope NewSouthWales/australiaeast (australiaeast)/ +NewZealandNorth/newzealandnorth +(newzealandnorth)/ Ohio(us-east-2)/us-east-2 Oregon(us-west-2)/us-west-2 Oregon(us-west1)/us-west1 From 1a41aa99261f00b9233016a2cdcb9e86900710ab Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 3 Mar 2025 14:24:32 +0100 Subject: [PATCH 263/659] set to clipboard after config changes --- scripts/cli/playground | 142 +++++++++--------- .../commands/connector/create-or-update.sh | 62 ++++---- 2 files changed, 102 insertions(+), 102 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index f63cffa6ce..e8ee7e2dde 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -25044,6 +25044,77 @@ playground_connector_create_or_update_command() { log "🔄 Updating $connector_type connector $connector" fi + if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] + then + if [[ -n "$offsets" ]] && [ $is_create == 0 ] + then + logerror "❌ --offsets is set but $connector_type connector $connector already exists" + exit 1 + fi + + if [[ -n "$initial_state" ]] + then + logerror "❌ --initial-state is set but not supported with $connector_type connector" + exit 1 + fi + + get_ccloud_connect + if [[ -n "$offsets" ]] + then + log "📍 creating $connector_type connector $connector with offsets: $offsets" + + # add mandatory name field + new_json_content=$(echo "$json_content" | jq -c ". + {\"name\": \"$connector\"}") + + sed -e "s|:CONNECTOR_NAME:|$connector|g" \ + -e "s|:CONNECTOR_CONFIG:|$new_json_content|g" \ + -e "s|:CONNECTOR_OFFSETS:|$offsets|g" \ + $root_folder/scripts/cli/src/create-connector-post-template.json > ${connector_with_offsets_file} + + handle_ccloud_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" -H \"authorization: Basic $authorization\" --data @$connector_with_offsets_file https://api.confluent.cloud/connect/v1/environments/$environment/clusters/$cluster/connectors" + else + handle_ccloud_connect_rest_api "curl $security -s -X PUT -H \"Content-Type: application/json\" -H \"authorization: Basic $authorization\" --data @$json_file https://api.confluent.cloud/connect/v1/environments/$environment/clusters/$cluster/connectors/$connector/config" + fi + else + if [[ -n "$offsets" ]] + then + logerror "❌ --offsets is set but not supported with $connector_type connector" + exit 1 + fi + if [[ -n "$initial_state" ]] && [ $is_create == 0 ] + then + logerror "❌ --initial-state is set but $connector_type connector $connector already exists" + exit 1 + fi + get_connect_url_and_security + if [[ -n "$skip_automatic_connector_config" ]] + then + log "🤖 --skip-automatic-connector-config is set" + else + add_connector_config_based_on_environment "$environment" "$json_content" + fi + + if [[ -n "$initial_state" ]] + then + log "🪵 creating $connector_type connector $connector with --initial-state: $initial_state" + + # add mandatory name field + new_json_content=$(echo "$json_content" | sed 's/&/:AMPERSAND:/g' | jq -c ". + {\"name\": \"$connector\"}") + + sed -e "s|:CONNECTOR_NAME:|$connector|g" \ + -e "s|:CONNECTOR_CONFIG:|$new_json_content|g" \ + -e "s|:CONNECTOR_INITIAL_STATE:|$initial_state|g" \ + $root_folder/scripts/cli/src/create-connector-post-template-initial-state.json > /tmp/connector_with_initial_state_file.json + + sed -e "s|:AMPERSAND:|\&|g" /tmp/connector_with_initial_state_file.json > ${connector_with_initial_state_file} + + handle_onprem_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" --data @$connector_with_initial_state_file $connect_url/connectors" + else + echo "$json_content" > $new_json_file + handle_onprem_connect_rest_api "curl $security -s -X PUT -H \"Content-Type: application/json\" --data @$new_json_file $connect_url/connectors/$connector/config" + fi + fi + echo "$json_content" > "/tmp/config-$connector" if [ -z "$GITHUB_RUN_NUMBER" ] @@ -25075,77 +25146,6 @@ playground_connector_create_or_update_command() { fi fi -if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] -then - if [[ -n "$offsets" ]] && [ $is_create == 0 ] - then - logerror "❌ --offsets is set but $connector_type connector $connector already exists" - exit 1 - fi - - if [[ -n "$initial_state" ]] - then - logerror "❌ --initial-state is set but not supported with $connector_type connector" - exit 1 - fi - - get_ccloud_connect - if [[ -n "$offsets" ]] - then - log "📍 creating $connector_type connector $connector with offsets: $offsets" - - # add mandatory name field - new_json_content=$(echo "$json_content" | jq -c ". + {\"name\": \"$connector\"}") - - sed -e "s|:CONNECTOR_NAME:|$connector|g" \ - -e "s|:CONNECTOR_CONFIG:|$new_json_content|g" \ - -e "s|:CONNECTOR_OFFSETS:|$offsets|g" \ - $root_folder/scripts/cli/src/create-connector-post-template.json > ${connector_with_offsets_file} - - handle_ccloud_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" -H \"authorization: Basic $authorization\" --data @$connector_with_offsets_file https://api.confluent.cloud/connect/v1/environments/$environment/clusters/$cluster/connectors" - else - handle_ccloud_connect_rest_api "curl $security -s -X PUT -H \"Content-Type: application/json\" -H \"authorization: Basic $authorization\" --data @$json_file https://api.confluent.cloud/connect/v1/environments/$environment/clusters/$cluster/connectors/$connector/config" - fi -else - if [[ -n "$offsets" ]] - then - logerror "❌ --offsets is set but not supported with $connector_type connector" - exit 1 - fi - if [[ -n "$initial_state" ]] && [ $is_create == 0 ] - then - logerror "❌ --initial-state is set but $connector_type connector $connector already exists" - exit 1 - fi - get_connect_url_and_security - if [[ -n "$skip_automatic_connector_config" ]] - then - log "🤖 --skip-automatic-connector-config is set" - else - add_connector_config_based_on_environment "$environment" "$json_content" - fi - - if [[ -n "$initial_state" ]] - then - log "🪵 creating $connector_type connector $connector with --initial-state: $initial_state" - - # add mandatory name field - new_json_content=$(echo "$json_content" | sed 's/&/:AMPERSAND:/g' | jq -c ". + {\"name\": \"$connector\"}") - - sed -e "s|:CONNECTOR_NAME:|$connector|g" \ - -e "s|:CONNECTOR_CONFIG:|$new_json_content|g" \ - -e "s|:CONNECTOR_INITIAL_STATE:|$initial_state|g" \ - $root_folder/scripts/cli/src/create-connector-post-template-initial-state.json > /tmp/connector_with_initial_state_file.json - - sed -e "s|:AMPERSAND:|\&|g" /tmp/connector_with_initial_state_file.json > ${connector_with_initial_state_file} - - handle_onprem_connect_rest_api "curl $security -s -X POST -H \"Content-Type: application/json\" --data @$connector_with_initial_state_file $connect_url/connectors" - else - echo "$json_content" > $new_json_file - handle_onprem_connect_rest_api "curl $security -s -X PUT -H \"Content-Type: application/json\" --data @$new_json_file $connect_url/connectors/$connector/config" - fi -fi - if [[ -n "$level" ]] then if [[ -n "$package" ]] diff --git a/scripts/cli/src/commands/connector/create-or-update.sh b/scripts/cli/src/commands/connector/create-or-update.sh index d0b25f6c8f..68e33960ed 100644 --- a/scripts/cli/src/commands/connector/create-or-update.sh +++ b/scripts/cli/src/commands/connector/create-or-update.sh @@ -191,37 +191,6 @@ else log "🔄 Updating $connector_type connector $connector" fi -echo "$json_content" > "/tmp/config-$connector" - -if [ -z "$GITHUB_RUN_NUMBER" ] -then - if [[ "$OSTYPE" == "darwin"* ]] - then - clipboard=$(playground config get clipboard) - if [ "$clipboard" == "" ] - then - playground config set clipboard true - fi - - if ( [ "$clipboard" == "true" ] || [ "$clipboard" == "" ] ) && [[ ! -n "$no_clipboard" ]] - then - tmp_dir_clipboard=$(mktemp -d -t pg-XXXXXXXXXX) - if [ -z "$PG_VERBOSE_MODE" ] - then - trap 'rm -rf $tmp_dir_clipboard' EXIT - else - log "🐛📂 not deleting tmp dir $tmp_dir_clipboard" - fi - echo "playground connector create-or-update --connector $connector << EOF" > $tmp_dir_clipboard/tmp - cat "/tmp/config-$connector" | jq -S . | sed 's/\$/\\$/g' >> $tmp_dir_clipboard/tmp - echo "EOF" >> $tmp_dir_clipboard/tmp - - cat $tmp_dir_clipboard/tmp | pbcopy - log "📋 $connector_type connector config has been copied to the clipboard (disable with 'playground config clipboard false')" - fi - fi -fi - if [ "$connector_type" == "$CONNECTOR_TYPE_FULLY_MANAGED" ] || [ "$connector_type" == "$CONNECTOR_TYPE_CUSTOM" ] then if [[ -n "$offsets" ]] && [ $is_create == 0 ] @@ -291,6 +260,37 @@ else fi fi +echo "$json_content" > "/tmp/config-$connector" + +if [ -z "$GITHUB_RUN_NUMBER" ] +then + if [[ "$OSTYPE" == "darwin"* ]] + then + clipboard=$(playground config get clipboard) + if [ "$clipboard" == "" ] + then + playground config set clipboard true + fi + + if ( [ "$clipboard" == "true" ] || [ "$clipboard" == "" ] ) && [[ ! -n "$no_clipboard" ]] + then + tmp_dir_clipboard=$(mktemp -d -t pg-XXXXXXXXXX) + if [ -z "$PG_VERBOSE_MODE" ] + then + trap 'rm -rf $tmp_dir_clipboard' EXIT + else + log "🐛📂 not deleting tmp dir $tmp_dir_clipboard" + fi + echo "playground connector create-or-update --connector $connector << EOF" > $tmp_dir_clipboard/tmp + cat "/tmp/config-$connector" | jq -S . | sed 's/\$/\\$/g' >> $tmp_dir_clipboard/tmp + echo "EOF" >> $tmp_dir_clipboard/tmp + + cat $tmp_dir_clipboard/tmp | pbcopy + log "📋 $connector_type connector config has been copied to the clipboard (disable with 'playground config clipboard false')" + fi + fi +fi + if [[ -n "$level" ]] then if [[ -n "$package" ]] From 3d51c3f25b62addd68e45c387e386f8a534887b4 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 4 Mar 2025 10:23:08 +0100 Subject: [PATCH 264/659] wip --- secrets.tar.gpg | Bin 7832 -> 7784 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/secrets.tar.gpg b/secrets.tar.gpg index 535396e3b0d0c888bb8baa6418a7a8801b1f2441..af9e6ecc4ddf61ab77eafd6ef436bb8c456bacb8 100644 GIT binary patch literal 7784 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 From 01c5fe5c3234c11f4f2d893c488337d0d3dbe4cc Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 4 Mar 2025 10:57:20 +0100 Subject: [PATCH 265/659] =?UTF-8?q?=F0=9F=90=9B=20Azure=20Functions=20requ?= =?UTF-8?q?ires=20AZ=5FUSER=20and=20AZ=5FPASS=20#6343?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fully-managed-azure-blob-storage-sink.sh | 15 +----------- ...fully-managed-azure-blob-storage-source.sh | 15 +----------- ...lly-managed-azure-cognitive-search-sink.sh | 15 +----------- .../fully-managed-azure-cosmosdb-sink.sh | 15 +----------- .../fully-managed-azure-cosmosdb-source.sh | 15 +----------- ...naged-azure-data-lake-storage-gen2-sink.sh | 15 +----------- .../fully-managed-azure-functions-sink.sh | 15 +----------- .../fully-managed-azure-log-analytics-sink.sh | 15 +----------- ...ly-managed-azure-synapse-analytics-sink.sh | 15 +----------- .../azure-blob-storage-sink-proxy.sh | 15 +----------- .../azure-blob-storage-sink.sh | 15 +----------- ...-blob-storage-source-backup-and-restore.sh | 15 +----------- .../azure-blob-storage-source-generalized.sh | 15 +----------- ...storage-source-proxy-backup-and-restore.sh | 15 +----------- .../azure-cognitive-search-sink-proxy.sh | 15 +----------- .../azure-cognitive-search-sink.sh | 15 +----------- .../azure-cosmosdb-sink.sh | 15 +----------- .../azure-cosmosdb-source.sh | 15 +----------- .../azure-data-lake-storage-gen1-sink.sh | 23 +------------------ .../azure-data-lake-storage-gen2-sink.sh | 15 +----------- .../azure-event-hubs-source.sh | 15 +----------- .../azure-functions-sink.sh | 15 +----------- .../azure-service-bus-source.sh | 15 +----------- .../azure-synapse-analytics-sink.sh | 15 +----------- .../jdbc-azure-synapse-analytics-source.sh | 12 +--------- scripts/cli/playground | 18 +++++++++++++-- .../src/commands/cleanup-cloud-resources.sh | 2 +- scripts/cli/src/lib/utils_function.sh | 16 ++++++++++++- 28 files changed, 57 insertions(+), 359 deletions(-) diff --git a/ccloud/fm-azure-blob-storage-sink/fully-managed-azure-blob-storage-sink.sh b/ccloud/fm-azure-blob-storage-sink/fully-managed-azure-blob-storage-sink.sh index abc8edbdc8..b4ed4e7e82 100755 --- a/ccloud/fm-azure-blob-storage-sink/fully-managed-azure-blob-storage-sink.sh +++ b/ccloud/fm-azure-blob-storage-sink/fully-managed-azure-blob-storage-sink.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pgfm${USER}bk${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/ccloud/fm-azure-blob-storage-source/fully-managed-azure-blob-storage-source.sh b/ccloud/fm-azure-blob-storage-source/fully-managed-azure-blob-storage-source.sh index c0cc0ecacd..5fe7d395df 100755 --- a/ccloud/fm-azure-blob-storage-source/fully-managed-azure-blob-storage-source.sh +++ b/ccloud/fm-azure-blob-storage-source/fully-managed-azure-blob-storage-source.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pgfm${USER}bs${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/ccloud/fm-azure-cognitive-search-sink/fully-managed-azure-cognitive-search-sink.sh b/ccloud/fm-azure-cognitive-search-sink/fully-managed-azure-cognitive-search-sink.sh index 1255ba0f8c..fabcff876b 100755 --- a/ccloud/fm-azure-cognitive-search-sink/fully-managed-azure-cognitive-search-sink.sh +++ b/ccloud/fm-azure-cognitive-search-sink/fully-managed-azure-cognitive-search-sink.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pgfm${USER}s${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/ccloud/fm-azure-cosmosdb-sink/fully-managed-azure-cosmosdb-sink.sh b/ccloud/fm-azure-cosmosdb-sink/fully-managed-azure-cosmosdb-sink.sh index 01b8924ecf..2dcda17dc4 100755 --- a/ccloud/fm-azure-cosmosdb-sink/fully-managed-azure-cosmosdb-sink.sh +++ b/ccloud/fm-azure-cosmosdb-sink/fully-managed-azure-cosmosdb-sink.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription bootstrap_ccloud_environment diff --git a/ccloud/fm-azure-cosmosdb-source/fully-managed-azure-cosmosdb-source.sh b/ccloud/fm-azure-cosmosdb-source/fully-managed-azure-cosmosdb-source.sh index 4fc987dc11..59e28a7504 100755 --- a/ccloud/fm-azure-cosmosdb-source/fully-managed-azure-cosmosdb-source.sh +++ b/ccloud/fm-azure-cosmosdb-source/fully-managed-azure-cosmosdb-source.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription bootstrap_ccloud_environment diff --git a/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh b/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh index 1355f81f33..939f660007 100755 --- a/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh +++ b/ccloud/fm-azure-data-lake-storage-gen2-sink/fully-managed-azure-data-lake-storage-gen2-sink.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pgfm${USER}dl${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh b/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh index 151eb534b1..9661063351 100755 --- a/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh +++ b/ccloud/fm-azure-functions-sink/fully-managed-azure-functions-sink.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pgfm${USER}fm${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/ccloud/fm-azure-log-analytics-sink/fully-managed-azure-log-analytics-sink.sh b/ccloud/fm-azure-log-analytics-sink/fully-managed-azure-log-analytics-sink.sh index 8473a3ad90..1f31d5f9ae 100755 --- a/ccloud/fm-azure-log-analytics-sink/fully-managed-azure-log-analytics-sink.sh +++ b/ccloud/fm-azure-log-analytics-sink/fully-managed-azure-log-analytics-sink.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pgfm${USER}la${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/ccloud/fm-azure-synapse-analytics-sink/fully-managed-azure-synapse-analytics-sink.sh b/ccloud/fm-azure-synapse-analytics-sink/fully-managed-azure-synapse-analytics-sink.sh index 73ccb3195f..2d53369c9b 100755 --- a/ccloud/fm-azure-synapse-analytics-sink/fully-managed-azure-synapse-analytics-sink.sh +++ b/ccloud/fm-azure-synapse-analytics-sink/fully-managed-azure-synapse-analytics-sink.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pgfm${USER}wh${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/connect/connect-azure-blob-storage-sink/azure-blob-storage-sink-proxy.sh b/connect/connect-azure-blob-storage-sink/azure-blob-storage-sink-proxy.sh index 3493b741f1..3732e2d703 100755 --- a/connect/connect-azure-blob-storage-sink/azure-blob-storage-sink-proxy.sh +++ b/connect/connect-azure-blob-storage-sink/azure-blob-storage-sink-proxy.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pg${USER}bk${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/connect/connect-azure-blob-storage-sink/azure-blob-storage-sink.sh b/connect/connect-azure-blob-storage-sink/azure-blob-storage-sink.sh index b6a9d87ecb..acf74f3538 100755 --- a/connect/connect-azure-blob-storage-sink/azure-blob-storage-sink.sh +++ b/connect/connect-azure-blob-storage-sink/azure-blob-storage-sink.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pg${USER}bk${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/connect/connect-azure-blob-storage-source/azure-blob-storage-source-backup-and-restore.sh b/connect/connect-azure-blob-storage-source/azure-blob-storage-source-backup-and-restore.sh index 1e69a891bb..7ffa952fea 100755 --- a/connect/connect-azure-blob-storage-source/azure-blob-storage-source-backup-and-restore.sh +++ b/connect/connect-azure-blob-storage-source/azure-blob-storage-source-backup-and-restore.sh @@ -10,20 +10,7 @@ then exit 111 fi -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pg${USER}bs${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/connect/connect-azure-blob-storage-source/azure-blob-storage-source-generalized.sh b/connect/connect-azure-blob-storage-source/azure-blob-storage-source-generalized.sh index 92c1ca541c..3111224ce8 100755 --- a/connect/connect-azure-blob-storage-source/azure-blob-storage-source-generalized.sh +++ b/connect/connect-azure-blob-storage-source/azure-blob-storage-source-generalized.sh @@ -16,20 +16,7 @@ then exit 111 fi -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pg${USER}bs${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/connect/connect-azure-blob-storage-source/azure-blob-storage-source-proxy-backup-and-restore.sh b/connect/connect-azure-blob-storage-source/azure-blob-storage-source-proxy-backup-and-restore.sh index 336aaec28c..f45bfcd72d 100755 --- a/connect/connect-azure-blob-storage-source/azure-blob-storage-source-proxy-backup-and-restore.sh +++ b/connect/connect-azure-blob-storage-source/azure-blob-storage-source-proxy-backup-and-restore.sh @@ -10,20 +10,7 @@ then exit 111 fi -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pg${USER}bs${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/connect/connect-azure-cognitive-search-sink/azure-cognitive-search-sink-proxy.sh b/connect/connect-azure-cognitive-search-sink/azure-cognitive-search-sink-proxy.sh index d5f885e73a..cee6462791 100755 --- a/connect/connect-azure-cognitive-search-sink/azure-cognitive-search-sink-proxy.sh +++ b/connect/connect-azure-cognitive-search-sink/azure-cognitive-search-sink-proxy.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pg${USER}s${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/connect/connect-azure-cognitive-search-sink/azure-cognitive-search-sink.sh b/connect/connect-azure-cognitive-search-sink/azure-cognitive-search-sink.sh index 81c5f988b8..75d810183e 100755 --- a/connect/connect-azure-cognitive-search-sink/azure-cognitive-search-sink.sh +++ b/connect/connect-azure-cognitive-search-sink/azure-cognitive-search-sink.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pg${USER}s${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/connect/connect-azure-cosmosdb-sink/azure-cosmosdb-sink.sh b/connect/connect-azure-cosmosdb-sink/azure-cosmosdb-sink.sh index a8e8c251f4..00ef75b52d 100755 --- a/connect/connect-azure-cosmosdb-sink/azure-cosmosdb-sink.sh +++ b/connect/connect-azure-cosmosdb-sink/azure-cosmosdb-sink.sh @@ -10,20 +10,7 @@ if ! version_gt $TAG_BASE "5.9.99"; then exit 111 fi -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription # https://github.com/microsoft/kafka-connect-cosmosdb/blob/dev/doc/CosmosDB_Setup.md AZURE_NAME=pg${USER}cs${GITHUB_RUN_NUMBER}${TAG} diff --git a/connect/connect-azure-cosmosdb-source/azure-cosmosdb-source.sh b/connect/connect-azure-cosmosdb-source/azure-cosmosdb-source.sh index 99757cc7cd..4375c6a231 100755 --- a/connect/connect-azure-cosmosdb-source/azure-cosmosdb-source.sh +++ b/connect/connect-azure-cosmosdb-source/azure-cosmosdb-source.sh @@ -10,20 +10,7 @@ if ! version_gt $TAG_BASE "5.9.99"; then exit 111 fi -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription # https://github.com/microsoft/kafka-connect-cosmosdb/blob/dev/doc/CosmosDB_Setup.md AZURE_NAME=pg${USER}ck${GITHUB_RUN_NUMBER}${TAG} diff --git a/connect/connect-azure-data-lake-storage-gen1-sink/azure-data-lake-storage-gen1-sink.sh b/connect/connect-azure-data-lake-storage-gen1-sink/azure-data-lake-storage-gen1-sink.sh index 962f216740..699707aada 100755 --- a/connect/connect-azure-data-lake-storage-gen1-sink/azure-data-lake-storage-gen1-sink.sh +++ b/connect/connect-azure-data-lake-storage-gen1-sink/azure-data-lake-storage-gen1-sink.sh @@ -7,28 +7,7 @@ source ${DIR}/../../scripts/utils.sh logwarn "Azure Data Lake Storage Gen1 will be retired 29 February 2024" check_if_continue -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -AZURE_SUBSCRIPTION_NAME=${AZURE_SUBSCRIPTION_NAME:-$1} - -if [ -z "$AZURE_SUBSCRIPTION_NAME" ] -then - logerror "AZURE_SUBSCRIPTION_NAME is not set. Export it as environment variable or pass it as argument" - exit 1 -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pg${USER}dl${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/connect/connect-azure-data-lake-storage-gen2-sink/azure-data-lake-storage-gen2-sink.sh b/connect/connect-azure-data-lake-storage-gen2-sink/azure-data-lake-storage-gen2-sink.sh index 31cdb99c30..e8ff99632d 100755 --- a/connect/connect-azure-data-lake-storage-gen2-sink/azure-data-lake-storage-gen2-sink.sh +++ b/connect/connect-azure-data-lake-storage-gen2-sink/azure-data-lake-storage-gen2-sink.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pg${USER}dl${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/connect/connect-azure-event-hubs-source/azure-event-hubs-source.sh b/connect/connect-azure-event-hubs-source/azure-event-hubs-source.sh index ff9e6bb9f4..3262429ffc 100755 --- a/connect/connect-azure-event-hubs-source/azure-event-hubs-source.sh +++ b/connect/connect-azure-event-hubs-source/azure-event-hubs-source.sh @@ -19,20 +19,7 @@ do set -e done -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pg${USER}eh${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/connect/connect-azure-functions-sink/azure-functions-sink.sh b/connect/connect-azure-functions-sink/azure-functions-sink.sh index 98e5089199..d0adc20853 100755 --- a/connect/connect-azure-functions-sink/azure-functions-sink.sh +++ b/connect/connect-azure-functions-sink/azure-functions-sink.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pg${USER}f${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/connect/connect-azure-service-bus-source/azure-service-bus-source.sh b/connect/connect-azure-service-bus-source/azure-service-bus-source.sh index 83ce91d55d..476721c227 100755 --- a/connect/connect-azure-service-bus-source/azure-service-bus-source.sh +++ b/connect/connect-azure-service-bus-source/azure-service-bus-source.sh @@ -21,20 +21,7 @@ do done cd - -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pg${USER}sb${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/connect/connect-azure-synapse-analytics-sink/azure-synapse-analytics-sink.sh b/connect/connect-azure-synapse-analytics-sink/azure-synapse-analytics-sink.sh index 6f58b5056b..7c48b382b4 100755 --- a/connect/connect-azure-synapse-analytics-sink/azure-synapse-analytics-sink.sh +++ b/connect/connect-azure-synapse-analytics-sink/azure-synapse-analytics-sink.sh @@ -4,20 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi - -# when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription -maybe_set_azure_subscription +login_and_maybe_set_azure_subscription AZURE_NAME=pg${USER}wh${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/connect/connect-jdbc-azure-synapse-analytics-source/jdbc-azure-synapse-analytics-source.sh b/connect/connect-jdbc-azure-synapse-analytics-source/jdbc-azure-synapse-analytics-source.sh index f219a04174..bb41513b87 100755 --- a/connect/connect-jdbc-azure-synapse-analytics-source/jdbc-azure-synapse-analytics-source.sh +++ b/connect/connect-jdbc-azure-synapse-analytics-source/jdbc-azure-synapse-analytics-source.sh @@ -14,17 +14,7 @@ then fi cd - -if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] -then - log "Logging to Azure using environment variables AZ_USER and AZ_PASS" - set +e - az logout - set -e - az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 -else - log "Logging to Azure using browser" - az login -fi +login_and_maybe_set_azure_subscription AZURE_NAME=pg${USER}wh${GITHUB_RUN_NUMBER}${TAG} AZURE_NAME=${AZURE_NAME//[-._]/} diff --git a/scripts/cli/playground b/scripts/cli/playground index e8ee7e2dde..dae0bdb087 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -12520,7 +12520,21 @@ function display_ngrok_warning () { check_if_continue } -function maybe_set_azure_subscription () { +function login_and_maybe_set_azure_subscription () { + + if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] + then + log "🫐 Logging to Azure using environment variables AZ_USER and AZ_PASS " + set +e + az logout + set -e + az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 + else + logerror "❌ AZ_USER and AZ_PASS environment variables are not set (for Confluent employees, that is simply your Confluent email address and Okta password)" + exit 1 + fi + + # when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription if [ ! -z "$AZURE_SUBSCRIPTION_NAME" ] then log "💙 AZURE_SUBSCRIPTION_NAME ($AZURE_SUBSCRIPTION_NAME) is set, searching for subscription id..." @@ -16426,7 +16440,7 @@ playground_cleanup_cloud_resources_command() { az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 fi - maybe_set_azure_subscription + login_and_maybe_set_azure_subscription log "Cleanup Azure Resource groups" for group in $(az group list --query '[].name' --output tsv) diff --git a/scripts/cli/src/commands/cleanup-cloud-resources.sh b/scripts/cli/src/commands/cleanup-cloud-resources.sh index 04342fd4d2..df42ad11d9 100644 --- a/scripts/cli/src/commands/cleanup-cloud-resources.sh +++ b/scripts/cli/src/commands/cleanup-cloud-resources.sh @@ -134,7 +134,7 @@ function cleanup_azure () { az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 fi - maybe_set_azure_subscription + login_and_maybe_set_azure_subscription log "Cleanup Azure Resource groups" for group in $(az group list --query '[].name' --output tsv) diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 7dacfcc1ac..03cf4e9c99 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -4251,7 +4251,21 @@ function display_ngrok_warning () { check_if_continue } -function maybe_set_azure_subscription () { +function login_and_maybe_set_azure_subscription () { + + if [ ! -z "$AZ_USER" ] && [ ! -z "$AZ_PASS" ] + then + log "🫐 Logging to Azure using environment variables AZ_USER and AZ_PASS " + set +e + az logout + set -e + az login -u "$AZ_USER" -p "$AZ_PASS" > /dev/null 2>&1 + else + logerror "❌ AZ_USER and AZ_PASS environment variables are not set (for Confluent employees, that is simply your Confluent email address and Okta password)" + exit 1 + fi + + # when AZURE_SUBSCRIPTION_NAME env var is set, we need to set the correct subscription if [ ! -z "$AZURE_SUBSCRIPTION_NAME" ] then log "💙 AZURE_SUBSCRIPTION_NAME ($AZURE_SUBSCRIPTION_NAME) is set, searching for subscription id..." From 6339ebaa0fc41111b10cd137b03274fd1e5875de Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 4 Mar 2025 10:58:18 +0100 Subject: [PATCH 266/659] =?UTF-8?q?=F0=9F=91=BE=20Remove=20Azure=20Data=20?= =?UTF-8?q?Lake=20Storage=20Gen1=20#6345?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../.gitignore | 1 - .../README.md | 20 --- .../azure-data-lake-storage-gen1-sink.sh | 116 ------------------ .../data.template | 4 - .../docker-compose.plaintext.yml | 7 -- .../stop.sh | 15 --- docs/content-template.md | 1 - 7 files changed, 164 deletions(-) delete mode 100644 connect/connect-azure-data-lake-storage-gen1-sink/.gitignore delete mode 100644 connect/connect-azure-data-lake-storage-gen1-sink/README.md delete mode 100755 connect/connect-azure-data-lake-storage-gen1-sink/azure-data-lake-storage-gen1-sink.sh delete mode 100644 connect/connect-azure-data-lake-storage-gen1-sink/data.template delete mode 100644 connect/connect-azure-data-lake-storage-gen1-sink/docker-compose.plaintext.yml delete mode 100755 connect/connect-azure-data-lake-storage-gen1-sink/stop.sh diff --git a/connect/connect-azure-data-lake-storage-gen1-sink/.gitignore b/connect/connect-azure-data-lake-storage-gen1-sink/.gitignore deleted file mode 100644 index 6320cd248d..0000000000 --- a/connect/connect-azure-data-lake-storage-gen1-sink/.gitignore +++ /dev/null @@ -1 +0,0 @@ -data \ No newline at end of file diff --git a/connect/connect-azure-data-lake-storage-gen1-sink/README.md b/connect/connect-azure-data-lake-storage-gen1-sink/README.md deleted file mode 100644 index 008c40460f..0000000000 --- a/connect/connect-azure-data-lake-storage-gen1-sink/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Azure Data Lake Storage Gen1 Sink connector - - - -## Objective - -Quickly test [Azure Data Lake Storage Gen1 Sink](https://docs.confluent.io/current/connect/kafka-connect-azure-data-lake-gen1-storage/index.html#quick-start) connector. - - -## How to run - -Simply run: - -``` -$ just use command and search for azure-data-lake-storage-gen1-sink.sh in this folder -``` - -**Note**: You need to provide the tenant name by providing AZURE_SUBSCRIPTION_NAME environment variable. Check the list of tenants using `az account list`. - -Note if you have multiple [Azure subscriptions](https://github.com/MicrosoftDocs/azure-docs-cli/blob/main/docs-ref-conceptual/manage-azure-subscriptions-azure-cli.md#change-the-active-subscription) make sure to set `AZURE_SUBSCRIPTION_NAME` environment variable to create Azure resource group in correct subscription (for confluent support, subscription is `COPS`). \ No newline at end of file diff --git a/connect/connect-azure-data-lake-storage-gen1-sink/azure-data-lake-storage-gen1-sink.sh b/connect/connect-azure-data-lake-storage-gen1-sink/azure-data-lake-storage-gen1-sink.sh deleted file mode 100755 index 699707aada..0000000000 --- a/connect/connect-azure-data-lake-storage-gen1-sink/azure-data-lake-storage-gen1-sink.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/bash -set -e - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -source ${DIR}/../../scripts/utils.sh - -logwarn "Azure Data Lake Storage Gen1 will be retired 29 February 2024" -check_if_continue - -login_and_maybe_set_azure_subscription - -AZURE_NAME=pg${USER}dl${GITHUB_RUN_NUMBER}${TAG} -AZURE_NAME=${AZURE_NAME//[-._]/} -AZURE_RESOURCE_GROUP=$AZURE_NAME -AZURE_DATALAKE_ACCOUNT_NAME=$AZURE_NAME -AZURE_AD_APP_NAME=$AZURE_NAME -AZURE_REGION=westeurope - -set +e -az group delete --name $AZURE_RESOURCE_GROUP --yes -AZURE_DATALAKE_CLIENT_ID=$(az ad app create --display-name "$AZURE_AD_APP_NAME" --is-fallback-public-client false --sign-in-audience AzureADandPersonalMicrosoftAccount --query appId -o tsv) -az ad app delete --id $AZURE_DATALAKE_CLIENT_ID -set -e - -log "Creating resource $AZURE_RESOURCE_GROUP in $AZURE_REGION" -az group create \ - --name $AZURE_RESOURCE_GROUP \ - --location $AZURE_REGION \ - --tags owner_email=$AZ_USER - -function cleanup_cloud_resources { - set +e - log "Deleting resource group $AZURE_RESOURCE_GROUP" - check_if_continue - az group delete --name $AZURE_RESOURCE_GROUP --yes --no-wait -} -trap cleanup_cloud_resources EXIT - -log "Registering active directory App $AZURE_AD_APP_NAME" -AZURE_DATALAKE_CLIENT_ID=$(az ad app create --display-name "$AZURE_AD_APP_NAME" --is-fallback-public-client false --sign-in-audience AzureADandPersonalMicrosoftAccount --query appId -o tsv) -AZURE_DATALAKE_CLIENT_PASSWORD=$(az ad app credential reset --id $AZURE_DATALAKE_CLIENT_ID | jq -r '.password') - -if [ "$AZURE_DATALAKE_CLIENT_PASSWORD" == "" ] -then - logerror "password could not be retrieved" - if [ -z "$GITHUB_RUN_NUMBER" ] - then - az ad app credential reset --id $AZURE_DATALAKE_CLIENT_ID - fi - exit 1 -fi - -log "Creating Service Principal associated to the App" -SERVICE_PRINCIPAL_ID=$(az ad sp create --id $AZURE_DATALAKE_CLIENT_ID | jq -r '.id') - -AZURE_TENANT_ID=$(az account list --query "[?name=='$AZURE_SUBSCRIPTION_NAME']" | jq -r '.[].tenantId') -AZURE_DATALAKE_TOKEN_ENDPOINT="https://login.microsoftonline.com/$AZURE_TENANT_ID/oauth2/token" - -log "Creating data lake $AZURE_DATALAKE_ACCOUNT_NAME in resource $AZURE_RESOURCE_GROUP" -az dls account create --account $AZURE_DATALAKE_ACCOUNT_NAME --resource-group $AZURE_RESOURCE_GROUP - -log "Giving permission to app $AZURE_AD_APP_NAME to get access to data lake $AZURE_DATALAKE_ACCOUNT_NAME" -az dls fs access set-entry --account $AZURE_DATALAKE_ACCOUNT_NAME --acl-spec user:$SERVICE_PRINCIPAL_ID:rwx --path / - -# generate data file for externalizing secrets -sed -e "s|:AZURE_DATALAKE_CLIENT_ID:|$AZURE_DATALAKE_CLIENT_ID|g" \ - -e "s|:AZURE_DATALAKE_CLIENT_PASSWORD:|$AZURE_DATALAKE_CLIENT_PASSWORD|g" \ - -e "s|:AZURE_DATALAKE_ACCOUNT_NAME:|$AZURE_DATALAKE_ACCOUNT_NAME|g" \ - -e "s|:AZURE_DATALAKE_TOKEN_ENDPOINT:|$AZURE_DATALAKE_TOKEN_ENDPOINT|g" \ - ../../connect/connect-azure-data-lake-storage-gen1-sink/data.template > ../../connect/connect-azure-data-lake-storage-gen1-sink/data - - -PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} -playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.yml" - -log "Creating Data Lake Storage Gen1 Sink connector" -playground connector create-or-update --connector azure-datalake-gen1-sink << EOF -{ - "connector.class": "io.confluent.connect.azure.datalake.gen1.AzureDataLakeGen1StorageSinkConnector", - "tasks.max": "1", - "topics": "datalake_topic", - "flush.size": "3", - "azure.datalake.client.id": "\${file:/data:AZURE_DATALAKE_CLIENT_ID}", - "azure.datalake.client.key": "\${file:/data:AZURE_DATALAKE_CLIENT_PASSWORD}", - "azure.datalake.account.name": "\${file:/data:AZURE_DATALAKE_ACCOUNT_NAME}", - "azure.datalake.token.endpoint": "\${file:/data:AZURE_DATALAKE_TOKEN_ENDPOINT}", - "format.class": "io.confluent.connect.azure.storage.format.avro.AvroFormat", - "confluent.license": "", - "confluent.topic.bootstrap.servers": "broker:9092", - "confluent.topic.replication.factor": "1" -} -EOF - - -playground topic produce -t datalake_topic --nb-messages 10 --forced-value '{"f1":"value%g"}' << 'EOF' -{ - "type": "record", - "name": "myrecord", - "fields": [ - { - "name": "f1", - "type": "string" - } - ] -} -EOF - -sleep 20 - -log "Listing ${AZURE_DATALAKE_ACCOUNT_NAME} in Azure Data Lake" -az dls fs list --account "${AZURE_DATALAKE_ACCOUNT_NAME}" --path /topics - -log "Getting one of the avro files locally and displaying content with avro-tools" -az dls fs download --account "${AZURE_DATALAKE_ACCOUNT_NAME}" --overwrite --source-path /topics/datalake_topic/partition=0/datalake_topic+0+0000000000.avro --destination-path /tmp/datalake_topic+0+0000000000.avro - -playground tools read-avro-file --file /tmp/datalake_topic+0+0000000000.avro \ No newline at end of file diff --git a/connect/connect-azure-data-lake-storage-gen1-sink/data.template b/connect/connect-azure-data-lake-storage-gen1-sink/data.template deleted file mode 100644 index 53e54c614b..0000000000 --- a/connect/connect-azure-data-lake-storage-gen1-sink/data.template +++ /dev/null @@ -1,4 +0,0 @@ -AZURE_DATALAKE_CLIENT_ID=:AZURE_DATALAKE_CLIENT_ID: -AZURE_DATALAKE_CLIENT_PASSWORD=:AZURE_DATALAKE_CLIENT_PASSWORD: -AZURE_DATALAKE_ACCOUNT_NAME=:AZURE_DATALAKE_ACCOUNT_NAME: -AZURE_DATALAKE_TOKEN_ENDPOINT=:AZURE_DATALAKE_TOKEN_ENDPOINT: \ No newline at end of file diff --git a/connect/connect-azure-data-lake-storage-gen1-sink/docker-compose.plaintext.yml b/connect/connect-azure-data-lake-storage-gen1-sink/docker-compose.plaintext.yml deleted file mode 100644 index f82f3f3b53..0000000000 --- a/connect/connect-azure-data-lake-storage-gen1-sink/docker-compose.plaintext.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -services: - connect: - volumes: - - ../../connect/connect-azure-data-lake-storage-gen1-sink/data:/data - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-azure-data-lake-gen1-storage \ No newline at end of file diff --git a/connect/connect-azure-data-lake-storage-gen1-sink/stop.sh b/connect/connect-azure-data-lake-storage-gen1-sink/stop.sh deleted file mode 100755 index cf432bae34..0000000000 --- a/connect/connect-azure-data-lake-storage-gen1-sink/stop.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - - - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -source ${DIR}/../../scripts/utils.sh - -stop_all "$DIR" - -AZURE_NAME=pg${USER}dl${GITHUB_RUN_NUMBER}${TAG} -AZURE_NAME=${AZURE_NAME//[-._]/} -AZURE_RESOURCE_GROUP=$AZURE_NAME - -log "Deleting resource group" -az group delete --name $AZURE_RESOURCE_GROUP --yes --no-wait \ No newline at end of file diff --git a/docs/content-template.md b/docs/content-template.md index d0e92d93e8..3e20a51a11 100644 --- a/docs/content-template.md +++ b/docs/content-template.md @@ -22,7 +22,6 @@ * [Azure Blob Storage Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-azure-blob-storage-source) (also with 🌐 proxy) :connect/connect-azure-blob-storage-source: * [Azure Cosmos DB Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-azure-cosmosdb-sink) :connect/connect-azure-cosmosdb-sink: * [Azure Cosmos DB Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-azure-cosmosdb-source) :connect/connect-azure-cosmosdb-source: -* [Azure Data Lake Storage Gen1 Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-azure-data-lake-storage-gen1-sink) ![not tested](https://img.shields.io/badge/CI-not%20tested!-violet) * [Azure Data Lake Storage Gen2 Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-azure-data-lake-storage-gen2-sink) :connect/connect-azure-data-lake-storage-gen2-sink: * [Azure Event Hubs Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-azure-event-hubs-source) :connect/connect-azure-event-hubs-source: * [Azure Functions Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-azure-functions-sink) :connect/connect-azure-functions-sink: From e5a5ce875e1493062ed315403703f2de1b16d269 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 4 Mar 2025 14:18:18 +0100 Subject: [PATCH 267/659] =?UTF-8?q?=F0=9F=A7=A0=20ignore=20.git=20folder?= =?UTF-8?q?=20in=20playground=20ec2=20local-to-ec2=20and=20ec2-to-local=20?= =?UTF-8?q?#6346?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 4 ++-- .../cli/src/commands/ec2/sync-repro-folder/ec2-to-local.sh | 2 +- .../cli/src/commands/ec2/sync-repro-folder/local-to-ec2.sh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index dae0bdb087..3bd16c0dcd 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -25765,7 +25765,7 @@ playground_ec2_sync_repro_folder_local_to_ec2_command() { ip=$(echo "${instance}" | cut -d "/" -f 3) log "👉 Sync local reproduction-models folder to ec2 instance $name" - rsync -cauv --filter=':- .gitignore' -e "ssh -i $pem_file -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" "$root_folder/reproduction-models" "$username@$ip:/home/$username/kafka-docker-playground" + rsync -cauv --exclude '.git' --filter=':- .gitignore' -e "ssh -i $pem_file -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" "$root_folder/reproduction-models" "$username@$ip:/home/$username/kafka-docker-playground" done } @@ -25821,7 +25821,7 @@ playground_ec2_sync_repro_folder_ec2_to_local_command() { ip=$(echo "${instance}" | cut -d "/" -f 3) log "👈 Sync ec2 instance $name reproduction-models folder to local" - rsync -cauv --filter=':- .gitignore' -e "ssh -i $pem_file -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" "$username@$ip:/home/$username/kafka-docker-playground/reproduction-models" "$root_folder" + rsync -cauv --exclude '.git' --filter=':- .gitignore' -e "ssh -i $pem_file -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" "$username@$ip:/home/$username/kafka-docker-playground/reproduction-models" "$root_folder" done } diff --git a/scripts/cli/src/commands/ec2/sync-repro-folder/ec2-to-local.sh b/scripts/cli/src/commands/ec2/sync-repro-folder/ec2-to-local.sh index 29766631bf..f7ebf920f9 100644 --- a/scripts/cli/src/commands/ec2/sync-repro-folder/ec2-to-local.sh +++ b/scripts/cli/src/commands/ec2/sync-repro-folder/ec2-to-local.sh @@ -47,5 +47,5 @@ do ip=$(echo "${instance}" | cut -d "/" -f 3) log "👈 Sync ec2 instance $name reproduction-models folder to local" - rsync -cauv --filter=':- .gitignore' -e "ssh -i $pem_file -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" "$username@$ip:/home/$username/kafka-docker-playground/reproduction-models" "$root_folder" + rsync -cauv --exclude '.git' --filter=':- .gitignore' -e "ssh -i $pem_file -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" "$username@$ip:/home/$username/kafka-docker-playground/reproduction-models" "$root_folder" done \ No newline at end of file diff --git a/scripts/cli/src/commands/ec2/sync-repro-folder/local-to-ec2.sh b/scripts/cli/src/commands/ec2/sync-repro-folder/local-to-ec2.sh index 19ac5b4e14..3c138dacc0 100644 --- a/scripts/cli/src/commands/ec2/sync-repro-folder/local-to-ec2.sh +++ b/scripts/cli/src/commands/ec2/sync-repro-folder/local-to-ec2.sh @@ -47,5 +47,5 @@ do ip=$(echo "${instance}" | cut -d "/" -f 3) log "👉 Sync local reproduction-models folder to ec2 instance $name" - rsync -cauv --filter=':- .gitignore' -e "ssh -i $pem_file -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" "$root_folder/reproduction-models" "$username@$ip:/home/$username/kafka-docker-playground" + rsync -cauv --exclude '.git' --filter=':- .gitignore' -e "ssh -i $pem_file -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" "$root_folder/reproduction-models" "$username@$ip:/home/$username/kafka-docker-playground" done \ No newline at end of file From 1620bf5020ca36aa91d463f5312c7699eadb010c Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 4 Mar 2025 14:18:26 +0100 Subject: [PATCH 268/659] remove debug --- .../connect-azure-functions-sink/azure-functions-sink.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/connect/connect-azure-functions-sink/azure-functions-sink.sh b/connect/connect-azure-functions-sink/azure-functions-sink.sh index d0adc20853..0b72bfce20 100755 --- a/connect/connect-azure-functions-sink/azure-functions-sink.sh +++ b/connect/connect-azure-functions-sink/azure-functions-sink.sh @@ -86,12 +86,6 @@ do fi done -set +e -curl -s https://$AZURE_FUNCTIONS_NAME.azurewebsites.net/" > /dev/null -curl -s https://$AZURE_FUNCTIONS_NAME.azurewebsites.net/api/httpexample" > /dev/null - -set -e - max_attempts="10" sleep_interval="30" attempt_num=1 @@ -100,8 +94,6 @@ until [ ! -z "$FUNCTIONS_URL" ] do output=$(docker run -v $PWD/LocalFunctionProj:/LocalFunctionProj mcr.microsoft.com/azure-functions/node:4-node20-core-tools bash -c "az login -u \"$AZ_USER\" -p \"$AZ_PASS\" > /dev/null 2>&1 && cd LocalFunctionProj && func azure functionapp list-functions \"$AZURE_FUNCTIONS_NAME\" --show-keys") - log "Output from list-functions command: $output" - FUNCTIONS_URL=$(echo "$output" | grep "Invoke url" | grep -Eo 'https://[^ >]+' | head -1) if [ ! -z "$FUNCTIONS_URL" ] From f72254450584e57f19e99220d8621e90362dabf4 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 4 Mar 2025 14:58:11 +0100 Subject: [PATCH 269/659] wip --- scripts/cli/playground | 3 +-- scripts/cli/src/commands/run.sh | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 3bd16c0dcd..41a729469e 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -14476,8 +14476,7 @@ playground_run_command() { fi sql_datagen=0 - if [[ $test_file == *"connect-debezium-sqlserver"* ]] || [[ $test_file == *"connect-debezium-mysql"* ]] || [[ $test_file == *"connect-debezium-postgresql"* ]] || [[ $test_file == *"connect-debezium-oracle"* ]] || [[ $test_file == *"connect-cdc-oracle"* ]] || [[ $test_file == *"connect-jdbc-sqlserver"* ]] || [[ $test_file == *"connect-jdbc-mysql"* ]] || [[ $test_file == *"connect-jdbc-postgresql"* ]] || [[ $test_file == *"connect-jdbc-oracle"* ]] - + if [[ $test_file == *"connect-debezium-sqlserver"* ]] || [[ $test_file == *"connect-debezium-mysql"* ]] || [[ $test_file == *"connect-debezium-postgresql"* ]] || [[ $test_file == *"connect-debezium-oracle"* ]] || [[ $test_file == *"connect-cdc-oracle"* ]] || [[ $test_file == *"connect-jdbc-sqlserver"* ]] || [[ $test_file == *"connect-jdbc-mysql"* ]] || [[ $test_file == *"connect-jdbc-postgresql"* ]] || [[ $test_file == *"connect-jdbc-oracle"* ]] || [[ $test_file == *"connect-cdc-xstream"* ]] then sql_datagen=1 fi diff --git a/scripts/cli/src/commands/run.sh b/scripts/cli/src/commands/run.sh index eb6c971e52..a4061cb704 100644 --- a/scripts/cli/src/commands/run.sh +++ b/scripts/cli/src/commands/run.sh @@ -549,7 +549,7 @@ then fi sql_datagen=0 - if [[ $test_file == *"connect-debezium-sqlserver"* ]] || [[ $test_file == *"connect-debezium-mysql"* ]] || [[ $test_file == *"connect-debezium-postgresql"* ]] || [[ $test_file == *"connect-debezium-oracle"* ]] || [[ $test_file == *"connect-cdc-oracle"* ]] || [[ $test_file == *"connect-jdbc-sqlserver"* ]] || [[ $test_file == *"connect-jdbc-mysql"* ]] || [[ $test_file == *"connect-jdbc-postgresql"* ]] || [[ $test_file == *"connect-jdbc-oracle"* ]] + if [[ $test_file == *"connect-debezium-sqlserver"* ]] || [[ $test_file == *"connect-debezium-mysql"* ]] || [[ $test_file == *"connect-debezium-postgresql"* ]] || [[ $test_file == *"connect-debezium-oracle"* ]] || [[ $test_file == *"connect-cdc-oracle"* ]] || [[ $test_file == *"connect-jdbc-sqlserver"* ]] || [[ $test_file == *"connect-jdbc-mysql"* ]] || [[ $test_file == *"connect-jdbc-postgresql"* ]] || [[ $test_file == *"connect-jdbc-oracle"* ]] || [[ $test_file == *"connect-cdc-xstream"* ]] then sql_datagen=1 fi From 498a61975c914c76272fa11c5cf779a1840eb06a Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 4 Mar 2025 15:17:20 +0100 Subject: [PATCH 270/659] wip oracle --- .../dashboards/debezium-connectors.json | 36 ++++++++----------- .../plaintext/jmx-exporter/kafka_connect.yml | 1 + 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/environment/plaintext/grafana/provisioning/dashboards/debezium-connectors.json b/environment/plaintext/grafana/provisioning/dashboards/debezium-connectors.json index 2bfed4f8fd..1967fa2b4a 100644 --- a/environment/plaintext/grafana/provisioning/dashboards/debezium-connectors.json +++ b/environment/plaintext/grafana/provisioning/dashboards/debezium-connectors.json @@ -25,8 +25,8 @@ "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 0, - "id": 16, - "iteration": 1720555864154, + "id": 11, + "iteration": 1741097725359, "links": [], "liveNow": false, "panels": [ @@ -60,7 +60,7 @@ }, "id": 76, "options": { - "content": "\n# Debezium Connector Metrics\n\nThe Debezium connectors has three metric types:\n\n* snapshot metrics\n\n* binlog metrics (MySql)\n\n* schema history metrics (MySql and SQLServer)\n\nFor more detailed informarion about the metrics please visit the Debezium documentation page\n\n[Click here to visit](https://debezium.io/documentation/reference/stable/operations/monitoring.html)\n\n\n\n", + "content": "\n# Debezium Connector Metrics\n\nThe Debezium connectors has three metric types:\n\n* snapshot metrics\n\n* binlog metrics (MySql)\n\n* schema history metrics (MySql, Confluent Oracle and SQLServer)\n\nFor more detailed informarion about the metrics please visit the Debezium documentation page\n\n[Click here to visit](https://debezium.io/documentation/reference/stable/operations/monitoring.html)\n\n\n\n", "mode": "markdown" }, "pluginVersion": "8.5.27", @@ -1903,8 +1903,7 @@ "mode": "absolute", "steps": [ { - "color": "semi-dark-blue", - "value": null + "color": "semi-dark-blue" }, { "color": "semi-dark-purple", @@ -2077,8 +2076,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2152,8 +2150,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2219,8 +2216,7 @@ "mode": "absolute", "steps": [ { - "color": "semi-dark-blue", - "value": null + "color": "semi-dark-blue" }, { "color": "dark-purple", @@ -2523,8 +2519,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2597,8 +2592,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2668,8 +2662,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -2913,15 +2906,16 @@ "debezium", "postgres", "mongodb", - "sqlserver" + "sqlserver", + "confluent oracle" ], "templating": { "list": [ { "current": { "selected": true, - "text": "server_mysql", - "value": "server_mysql" + "text": "All", + "value": "$__all" }, "datasource": { "type": "prometheus", @@ -3000,6 +2994,6 @@ "timezone": "browser", "title": "Debezium Connectors", "uid": "Ro1hBYYZz", - "version": 7, + "version": 2, "weekStart": "" } \ No newline at end of file diff --git a/environment/plaintext/jmx-exporter/kafka_connect.yml b/environment/plaintext/jmx-exporter/kafka_connect.yml index 9f39c38997..92dc7c3683 100644 --- a/environment/plaintext/jmx-exporter/kafka_connect.yml +++ b/environment/plaintext/jmx-exporter/kafka_connect.yml @@ -31,6 +31,7 @@ whitelistObjectNames: - "debezium.sql_server:*" - "debezium.mongodb:*" - "debezium.postgres:*" + - "debezium.confluent.oracle:*" blacklistObjectNames: # This will ignore the admin client metrics from KSQL server and will blacklist certain metrics # that do not make sense for ingestion. From b500437e07ee63ff172786e75bebbfa5a5866d95 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 4 Mar 2025 16:43:32 +0100 Subject: [PATCH 271/659] =?UTF-8?q?=F0=9F=A7=A0=20playground=20topic=20con?= =?UTF-8?q?sume=20shows=20SLF4J:=20Class=20path=20contains=20multiple=20SL?= =?UTF-8?q?F4J=20bindings=20#6344?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 3 +++ scripts/cli/src/commands/topic/consume.sh | 3 +++ 2 files changed, 6 insertions(+) diff --git a/scripts/cli/playground b/scripts/cli/playground index 41a729469e..cb7c6381de 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -20849,6 +20849,9 @@ playground_topic_consume_command() { then continue elif [[ $line =~ "Processed a total of" ]] + then + continue + elif [[ $line =~ "SLF4J" ]] then continue else diff --git a/scripts/cli/src/commands/topic/consume.sh b/scripts/cli/src/commands/topic/consume.sh index 214bdc2d5a..1372b7c9a9 100644 --- a/scripts/cli/src/commands/topic/consume.sh +++ b/scripts/cli/src/commands/topic/consume.sh @@ -457,6 +457,9 @@ fi then continue elif [[ $line =~ "Processed a total of" ]] + then + continue + elif [[ $line =~ "SLF4J" ]] then continue else From 0ab5ca14782d455726f2044d700c8276cd048baf Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 5 Mar 2025 10:05:42 +0100 Subject: [PATCH 272/659] wip --- scripts/cli/confluent-hub-plugin-list.txt | 2 +- scripts/cli/confluent-kafka-region-list.txt | 1 - scripts/cli/playground | 4 ++-- scripts/cli/src/commands/cleanup-cloud-resources.sh | 4 ++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index 2c6a862e9a..b4026d5d10 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -1,4 +1,3 @@ -Onibex/snowflake-sink-connector a2solutions/oracdc-kafka ably/kafka-connect-ably adobeinc/streaming-connect-sink @@ -168,6 +167,7 @@ neo4j/kafka-connect-neo4j newrelic/newrelic-kafka-connector onewayautomation/ogamma-visual-logger-for-opc onibex/onibex-databricks-sink-connector +onibex/snowflake-sink-connector opencredo/kafka-connect-venafi oracle/goldengate oticsinc/maads-viper diff --git a/scripts/cli/confluent-kafka-region-list.txt b/scripts/cli/confluent-kafka-region-list.txt index 281f100a85..4cdd63ac7e 100644 --- a/scripts/cli/confluent-kafka-region-list.txt +++ b/scripts/cli/confluent-kafka-region-list.txt @@ -25,7 +25,6 @@ Ireland(eu-west-1)/eu-west-1 Ireland(northeurope)/northeurope Jakarta(ap-southeast-3)/ap-southeast-3 Jakarta(asia-southeast2)/asia-southeast2 -JioIndiaWest(jioindiawest)/jioindiawest Johannesburg/southafricanorth (southafricanorth)/ LasVegas(us-west4)/us-west4 diff --git a/scripts/cli/playground b/scripts/cli/playground index cb7c6381de..0235e7fe70 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -16568,7 +16568,7 @@ EOF docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME\" -p \"$SALESFORCE_PASSWORD\" -r \"$SALESFORCE_INSTANCE\" -s \"$SALESFORCE_SECURITY_TOKEN\" && sfdx data:query --target-org \"$SALESFORCE_USERNAME\" -q \"SELECT Id FROM Contact\" --result-format csv > /tmp/out.csv && sfdx force:data:bulk:delete --target-org \"$SALESFORCE_USERNAME\" -s Contact -f /tmp/out.csv" log "Cleanup PushTopics on account with $SALESFORCE_USERNAME" - docker exec -i sfdx-cli sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME\"" << EOF + docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME\"" << EOF List pts = [SELECT Id FROM PushTopic]; Database.delete(pts); EOF @@ -16584,7 +16584,7 @@ EOF docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME_ACCOUNT2\" -p \"$SALESFORCE_PASSWORD_ACCOUNT2\" -r \"$SALESFORCE_INSTANCE_ACCOUNT2\" -s \"$SALESFORCE_SECURITY_TOKEN_ACCOUNT2\" && sfdx data:query --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\" -q \"SELECT Id FROM Contact\" --result-format csv > /tmp/out.csv && sfdx force:data:bulk:delete --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\" -s Contact -f /tmp/out.csv" log "Cleanup PushTopics on account with $SALESFORCE_USERNAME_ACCOUNT2" - docker exec -i sfdx-cli sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\"" << EOF + docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\"" << EOF List pts = [SELECT Id FROM PushTopic]; Database.delete(pts); EOF diff --git a/scripts/cli/src/commands/cleanup-cloud-resources.sh b/scripts/cli/src/commands/cleanup-cloud-resources.sh index df42ad11d9..fdab08cd57 100644 --- a/scripts/cli/src/commands/cleanup-cloud-resources.sh +++ b/scripts/cli/src/commands/cleanup-cloud-resources.sh @@ -263,7 +263,7 @@ function cleanup_salesforce () { docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME\" -p \"$SALESFORCE_PASSWORD\" -r \"$SALESFORCE_INSTANCE\" -s \"$SALESFORCE_SECURITY_TOKEN\" && sfdx data:query --target-org \"$SALESFORCE_USERNAME\" -q \"SELECT Id FROM Contact\" --result-format csv > /tmp/out.csv && sfdx force:data:bulk:delete --target-org \"$SALESFORCE_USERNAME\" -s Contact -f /tmp/out.csv" log "Cleanup PushTopics on account with $SALESFORCE_USERNAME" - docker exec -i sfdx-cli sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME\"" << EOF + docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME\"" << EOF List pts = [SELECT Id FROM PushTopic]; Database.delete(pts); EOF @@ -279,7 +279,7 @@ EOF docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME_ACCOUNT2\" -p \"$SALESFORCE_PASSWORD_ACCOUNT2\" -r \"$SALESFORCE_INSTANCE_ACCOUNT2\" -s \"$SALESFORCE_SECURITY_TOKEN_ACCOUNT2\" && sfdx data:query --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\" -q \"SELECT Id FROM Contact\" --result-format csv > /tmp/out.csv && sfdx force:data:bulk:delete --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\" -s Contact -f /tmp/out.csv" log "Cleanup PushTopics on account with $SALESFORCE_USERNAME_ACCOUNT2" - docker exec -i sfdx-cli sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\"" << EOF + docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\"" << EOF List pts = [SELECT Id FROM PushTopic]; Database.delete(pts); EOF From b0b1f449b477f9844b634723922406da448b8a7f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 5 Mar 2025 10:34:45 +0100 Subject: [PATCH 273/659] fix --- scripts/cli/playground | 4 ++-- scripts/cli/src/commands/cleanup-cloud-resources.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 0235e7fe70..952cebcade 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -16568,7 +16568,7 @@ EOF docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME\" -p \"$SALESFORCE_PASSWORD\" -r \"$SALESFORCE_INSTANCE\" -s \"$SALESFORCE_SECURITY_TOKEN\" && sfdx data:query --target-org \"$SALESFORCE_USERNAME\" -q \"SELECT Id FROM Contact\" --result-format csv > /tmp/out.csv && sfdx force:data:bulk:delete --target-org \"$SALESFORCE_USERNAME\" -s Contact -f /tmp/out.csv" log "Cleanup PushTopics on account with $SALESFORCE_USERNAME" - docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME\"" << EOF + docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME\" -p \"$SALESFORCE_PASSWORD\" -r \"$SALESFORCE_INSTANCE\" -s \"$SALESFORCE_SECURITY_TOKEN\" && sfdx apex run --target-org \"$SALESFORCE_USERNAME\"" << EOF List pts = [SELECT Id FROM PushTopic]; Database.delete(pts); EOF @@ -16584,7 +16584,7 @@ EOF docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME_ACCOUNT2\" -p \"$SALESFORCE_PASSWORD_ACCOUNT2\" -r \"$SALESFORCE_INSTANCE_ACCOUNT2\" -s \"$SALESFORCE_SECURITY_TOKEN_ACCOUNT2\" && sfdx data:query --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\" -q \"SELECT Id FROM Contact\" --result-format csv > /tmp/out.csv && sfdx force:data:bulk:delete --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\" -s Contact -f /tmp/out.csv" log "Cleanup PushTopics on account with $SALESFORCE_USERNAME_ACCOUNT2" - docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\"" << EOF + docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME_ACCOUNT2\" -p \"$SALESFORCE_PASSWORD_ACCOUNT2\" -r \"$SALESFORCE_INSTANCE_ACCOUNT2\" -s \"$SALESFORCE_SECURITY_TOKEN_ACCOUNT2\" && sfdx apex run --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\"" << EOF List pts = [SELECT Id FROM PushTopic]; Database.delete(pts); EOF diff --git a/scripts/cli/src/commands/cleanup-cloud-resources.sh b/scripts/cli/src/commands/cleanup-cloud-resources.sh index fdab08cd57..e79164aecc 100644 --- a/scripts/cli/src/commands/cleanup-cloud-resources.sh +++ b/scripts/cli/src/commands/cleanup-cloud-resources.sh @@ -263,7 +263,7 @@ function cleanup_salesforce () { docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME\" -p \"$SALESFORCE_PASSWORD\" -r \"$SALESFORCE_INSTANCE\" -s \"$SALESFORCE_SECURITY_TOKEN\" && sfdx data:query --target-org \"$SALESFORCE_USERNAME\" -q \"SELECT Id FROM Contact\" --result-format csv > /tmp/out.csv && sfdx force:data:bulk:delete --target-org \"$SALESFORCE_USERNAME\" -s Contact -f /tmp/out.csv" log "Cleanup PushTopics on account with $SALESFORCE_USERNAME" - docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME\"" << EOF + docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME\" -p \"$SALESFORCE_PASSWORD\" -r \"$SALESFORCE_INSTANCE\" -s \"$SALESFORCE_SECURITY_TOKEN\" && sfdx apex run --target-org \"$SALESFORCE_USERNAME\"" << EOF List pts = [SELECT Id FROM PushTopic]; Database.delete(pts); EOF @@ -279,7 +279,7 @@ EOF docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME_ACCOUNT2\" -p \"$SALESFORCE_PASSWORD_ACCOUNT2\" -r \"$SALESFORCE_INSTANCE_ACCOUNT2\" -s \"$SALESFORCE_SECURITY_TOKEN_ACCOUNT2\" && sfdx data:query --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\" -q \"SELECT Id FROM Contact\" --result-format csv > /tmp/out.csv && sfdx force:data:bulk:delete --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\" -s Contact -f /tmp/out.csv" log "Cleanup PushTopics on account with $SALESFORCE_USERNAME_ACCOUNT2" - docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx apex run --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\"" << EOF + docker run -i --rm vdesabou/sfdx-cli:latest sh -c "sfdx sfpowerkit:auth:login -u \"$SALESFORCE_USERNAME_ACCOUNT2\" -p \"$SALESFORCE_PASSWORD_ACCOUNT2\" -r \"$SALESFORCE_INSTANCE_ACCOUNT2\" -s \"$SALESFORCE_SECURITY_TOKEN_ACCOUNT2\" && sfdx apex run --target-org \"$SALESFORCE_USERNAME_ACCOUNT2\"" << EOF List pts = [SELECT Id FROM PushTopic]; Database.delete(pts); EOF From 1ebf4ddc99740372eb9f5b79cc8077448c34b117 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 5 Mar 2025 11:19:41 +0100 Subject: [PATCH 274/659] =?UTF-8?q?=F0=9F=91=BE=20Add=20example=20for=20Da?= =?UTF-8?q?taDog=20Logs=20Sink=20Connector=20#6347?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 2 +- docs/content-template.md | 1 + kafka-docker-playground.sln | 62 ------------------------------------- 3 files changed, 2 insertions(+), 63 deletions(-) delete mode 100644 kafka-docker-playground.sln diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 933ecc7f6f..721255d7d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -124,7 +124,7 @@ jobs: "🚀 connect/connect-http-sink connect/connect-iceberg-sink", "🚀 multi-data-center/replicator-connect", "🚀 multi-data-center/replicator-executable", - "🚀 multi-data-center/mirrormaker2 connect/connect-pagerduty-sink connect/connect-zendesk-source connect/connect-datadog-metrics-sink connect/connect-gcp-spanner-sink connect/connect-gcp-firebase-source connect/connect-gcp-firebase-sink", + "🚀 multi-data-center/mirrormaker2 connect/connect-pagerduty-sink connect/connect-zendesk-source connect/connect-datadog-metrics-sink connect/connect-datadog-logs-sink connect/connect-gcp-spanner-sink connect/connect-gcp-firebase-source connect/connect-gcp-firebase-sink", "🚀 other/filebeat-to-kafka other/rest-proxy-security-plugin other/tiered-storage-with-aws other/write-logs-to-files other/audit-logs schema-registry/multiple-event-types-in-topic other/broker-schema-validation other/schema-registry-security-plugin multi-data-center/cluster-linking other/secrets-management other/connect-secret-registry other/schema-format-protobuf other/schema-format-json-schema other/schema-format-avro", "🚀 ccloud/replicator ccloud/rest-proxy-security-plugin ccloud/schema-registry-security-plugin ccloud/audit-log-connector", "🚀 connect/connect-cdc-oracle12-source", diff --git a/docs/content-template.md b/docs/content-template.md index 3e20a51a11..9bfca2de0a 100644 --- a/docs/content-template.md +++ b/docs/content-template.md @@ -41,6 +41,7 @@ * [Data Diode Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-datadiode-source-sink) :connect/connect-datadiode-source-sink: * [Data Diode Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-datadiode-source-sink) :connect/connect-datadiode-source-sink: * [Datadog Metrics Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-datadog-metrics-sink) :connect/connect-datadog-metrics-sink: +* [Datadog Logs Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect/connect-datadog-logs-sink) :connect/connect/connect-datadog-logs-sink: * [ElasticSearch Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-elasticsearch-sink) :connect/connect-elasticsearch-sink: * [ElasticSearch Sink with Elastic Cloud](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-elasticsearch-cloud-sink) ![not tested](https://img.shields.io/badge/CI-not%20tested!-violet) * [FilePulse Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-filepulse-source) ![owner](https://img.shields.io/badge/-streamthoughts-blue) :connect/connect-filepulse-source: diff --git a/kafka-docker-playground.sln b/kafka-docker-playground.sln deleted file mode 100644 index 00d602f65b..0000000000 --- a/kafka-docker-playground.sln +++ /dev/null @@ -1,62 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.5.2.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "other", "other", "{A36FAAB1-3B70-FACF-6B1E-E7138A3CFC44}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ccloud", "ccloud", "{23A3CAC0-821E-7AD0-08BD-CA0EE349EAFD}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNet2.2", "other\client-dotnet\DotNet2.2.csproj", "{625BE235-268A-2C24-CBAB-2179484E8F6A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNet3.1", "other\client-dotnet\DotNet3.1.csproj", "{1D28699F-2914-0C47-88FD-02E4E032105F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CCloud2.2", "ccloud\client-dotnet\CCloud2.2.csproj", "{CC0B8A5C-26CF-D9A8-097D-D9817C56F10E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CCloud3.1", "ccloud\client-dotnet\CCloud3.1.csproj", "{E71428FB-D2F1-7DBE-3776-43AC8C44B9E1}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "monitoring-demo", "monitoring-demo", "{4828A052-A836-CE0D-A6B8-54B2D4A2BDD4}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Monitoring", "other\monitoring-demo\client-dotnet\Monitoring.csproj", "{D91C8015-30A1-65B8-CCA6-B575106E5070}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {625BE235-268A-2C24-CBAB-2179484E8F6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {625BE235-268A-2C24-CBAB-2179484E8F6A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {625BE235-268A-2C24-CBAB-2179484E8F6A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {625BE235-268A-2C24-CBAB-2179484E8F6A}.Release|Any CPU.Build.0 = Release|Any CPU - {1D28699F-2914-0C47-88FD-02E4E032105F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1D28699F-2914-0C47-88FD-02E4E032105F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1D28699F-2914-0C47-88FD-02E4E032105F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1D28699F-2914-0C47-88FD-02E4E032105F}.Release|Any CPU.Build.0 = Release|Any CPU - {CC0B8A5C-26CF-D9A8-097D-D9817C56F10E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CC0B8A5C-26CF-D9A8-097D-D9817C56F10E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CC0B8A5C-26CF-D9A8-097D-D9817C56F10E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CC0B8A5C-26CF-D9A8-097D-D9817C56F10E}.Release|Any CPU.Build.0 = Release|Any CPU - {E71428FB-D2F1-7DBE-3776-43AC8C44B9E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E71428FB-D2F1-7DBE-3776-43AC8C44B9E1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E71428FB-D2F1-7DBE-3776-43AC8C44B9E1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E71428FB-D2F1-7DBE-3776-43AC8C44B9E1}.Release|Any CPU.Build.0 = Release|Any CPU - {D91C8015-30A1-65B8-CCA6-B575106E5070}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D91C8015-30A1-65B8-CCA6-B575106E5070}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D91C8015-30A1-65B8-CCA6-B575106E5070}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D91C8015-30A1-65B8-CCA6-B575106E5070}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {625BE235-268A-2C24-CBAB-2179484E8F6A} = {A36FAAB1-3B70-FACF-6B1E-E7138A3CFC44} - {1D28699F-2914-0C47-88FD-02E4E032105F} = {A36FAAB1-3B70-FACF-6B1E-E7138A3CFC44} - {CC0B8A5C-26CF-D9A8-097D-D9817C56F10E} = {23A3CAC0-821E-7AD0-08BD-CA0EE349EAFD} - {E71428FB-D2F1-7DBE-3776-43AC8C44B9E1} = {23A3CAC0-821E-7AD0-08BD-CA0EE349EAFD} - {4828A052-A836-CE0D-A6B8-54B2D4A2BDD4} = {A36FAAB1-3B70-FACF-6B1E-E7138A3CFC44} - {D91C8015-30A1-65B8-CCA6-B575106E5070} = {4828A052-A836-CE0D-A6B8-54B2D4A2BDD4} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {D11B5B17-01D3-4289-9564-52BB9178AEC2} - EndGlobalSection -EndGlobal From 3db24ceff72eda289d946ecef288f0e5899e17d3 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 5 Mar 2025 13:48:34 +0100 Subject: [PATCH 275/659] wip --- .github/workflows/ci.yml | 2 +- docs/content-template.md | 2 +- tools/datadog/start.sh | 24 ++++++++++++------------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 721255d7d6..933ecc7f6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -124,7 +124,7 @@ jobs: "🚀 connect/connect-http-sink connect/connect-iceberg-sink", "🚀 multi-data-center/replicator-connect", "🚀 multi-data-center/replicator-executable", - "🚀 multi-data-center/mirrormaker2 connect/connect-pagerduty-sink connect/connect-zendesk-source connect/connect-datadog-metrics-sink connect/connect-datadog-logs-sink connect/connect-gcp-spanner-sink connect/connect-gcp-firebase-source connect/connect-gcp-firebase-sink", + "🚀 multi-data-center/mirrormaker2 connect/connect-pagerduty-sink connect/connect-zendesk-source connect/connect-datadog-metrics-sink connect/connect-gcp-spanner-sink connect/connect-gcp-firebase-source connect/connect-gcp-firebase-sink", "🚀 other/filebeat-to-kafka other/rest-proxy-security-plugin other/tiered-storage-with-aws other/write-logs-to-files other/audit-logs schema-registry/multiple-event-types-in-topic other/broker-schema-validation other/schema-registry-security-plugin multi-data-center/cluster-linking other/secrets-management other/connect-secret-registry other/schema-format-protobuf other/schema-format-json-schema other/schema-format-avro", "🚀 ccloud/replicator ccloud/rest-proxy-security-plugin ccloud/schema-registry-security-plugin ccloud/audit-log-connector", "🚀 connect/connect-cdc-oracle12-source", diff --git a/docs/content-template.md b/docs/content-template.md index 9bfca2de0a..f66cc3ac77 100644 --- a/docs/content-template.md +++ b/docs/content-template.md @@ -41,7 +41,7 @@ * [Data Diode Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-datadiode-source-sink) :connect/connect-datadiode-source-sink: * [Data Diode Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-datadiode-source-sink) :connect/connect-datadiode-source-sink: * [Datadog Metrics Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-datadog-metrics-sink) :connect/connect-datadog-metrics-sink: -* [Datadog Logs Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect/connect-datadog-logs-sink) :connect/connect/connect-datadog-logs-sink: +* [Datadog Logs Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect/connect-datadog-logs-sink) ![not tested](https://img.shields.io/badge/CI-not%20tested!-violet) * [ElasticSearch Sink](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-elasticsearch-sink) :connect/connect-elasticsearch-sink: * [ElasticSearch Sink with Elastic Cloud](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-elasticsearch-cloud-sink) ![not tested](https://img.shields.io/badge/CI-not%20tested!-violet) * [FilePulse Source](https://github.com/vdesabou/kafka-docker-playground/tree/master/connect/connect-filepulse-source) ![owner](https://img.shields.io/badge/-streamthoughts-blue) :connect/connect-filepulse-source: diff --git a/tools/datadog/start.sh b/tools/datadog/start.sh index b425ebfbe6..00c8c4865a 100755 --- a/tools/datadog/start.sh +++ b/tools/datadog/start.sh @@ -37,18 +37,18 @@ EOF log "Creating Replicator connector" playground connector create-or-update --connector duplicate-topic << EOF { - "connector.class":"io.confluent.connect.replicator.ReplicatorSourceConnector", - "key.converter": "io.confluent.connect.replicator.util.ByteArrayConverter", - "value.converter": "io.confluent.connect.replicator.util.ByteArrayConverter", - "header.converter": "io.confluent.connect.replicator.util.ByteArrayConverter", - "src.consumer.group.id": "duplicate-topic", - "confluent.topic.replication.factor": 1, - "provenance.header.enable": true, - "topic.whitelist": "test-topic", - "topic.rename.format": "test-topic-duplicate", - "dest.kafka.bootstrap.servers": "broker:9092", - "src.kafka.bootstrap.servers": "broker:9092" - } + "connector.class":"io.confluent.connect.replicator.ReplicatorSourceConnector", + "key.converter": "io.confluent.connect.replicator.util.ByteArrayConverter", + "value.converter": "io.confluent.connect.replicator.util.ByteArrayConverter", + "header.converter": "io.confluent.connect.replicator.util.ByteArrayConverter", + "src.consumer.group.id": "duplicate-topic", + "confluent.topic.replication.factor": 1, + "provenance.header.enable": true, + "topic.whitelist": "test-topic", + "topic.rename.format": "test-topic-duplicate", + "dest.kafka.bootstrap.servers": "broker:9092", + "src.kafka.bootstrap.servers": "broker:9092" +} EOF sleep 10 From e4ceff5c17301d416dcedf4b7866a9de0476c158 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 5 Mar 2025 15:28:06 +0100 Subject: [PATCH 276/659] Wildcard route to accept any path --- connect/connect-http-sink/httpserver/server.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/connect/connect-http-sink/httpserver/server.js b/connect/connect-http-sink/httpserver/server.js index 78836859fb..10ebd23b5f 100644 --- a/connect/connect-http-sink/httpserver/server.js +++ b/connect/connect-http-sink/httpserver/server.js @@ -20,6 +20,19 @@ app.use((req, res, next) => { next(); }); +// Wildcard route to accept any path +app.all('*', (req, res) => { + res.status(errorCode) + .set('Content-Type', 'application/json') + .set('Custom-Header', 'Hello') + .json(responseBody); + console.log("headers:"); + console.log(req.headers); + console.log("body:"); + console.log(req.body); + console.log(`[${new Date().toISOString()}] sending back ${errorCode}`); +}); + app.get('/', (req, res) => { res.status(errorCode) .set('Content-Type', 'application/json') From 4780bd820a2583ee8bba05b535878f5811efc429 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Mar 2025 09:27:42 +0100 Subject: [PATCH 277/659] wildcard at the end --- .../connect-http-sink/httpserver/server.js | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/connect/connect-http-sink/httpserver/server.js b/connect/connect-http-sink/httpserver/server.js index 10ebd23b5f..706215ee5c 100644 --- a/connect/connect-http-sink/httpserver/server.js +++ b/connect/connect-http-sink/httpserver/server.js @@ -20,19 +20,6 @@ app.use((req, res, next) => { next(); }); -// Wildcard route to accept any path -app.all('*', (req, res) => { - res.status(errorCode) - .set('Content-Type', 'application/json') - .set('Custom-Header', 'Hello') - .json(responseBody); - console.log("headers:"); - console.log(req.headers); - console.log("body:"); - console.log(req.body); - console.log(`[${new Date().toISOString()}] sending back ${errorCode}`); -}); - app.get('/', (req, res) => { res.status(errorCode) .set('Content-Type', 'application/json') @@ -108,4 +95,17 @@ app.put('/set-response-body', (req, res) => { } }); +// Wildcard route to accept any path +app.all('*', (req, res) => { + res.status(errorCode) + .set('Content-Type', 'application/json') + .set('Custom-Header', 'Hello') + .json(responseBody); + console.log("headers:"); + console.log(req.headers); + console.log("body:"); + console.log(req.body); + console.log(`[${new Date().toISOString()}] sending back ${errorCode}`); +}); + app.listen(9006, () => console.log('Server running...')); From 50c3c17c9729fcc8b8b96d8f84fafce86690a3dc Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Mar 2025 09:28:34 +0100 Subject: [PATCH 278/659] keep duplicates --- scripts/cli/playground | 4 ++-- scripts/cli/src/commands/history.sh | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 952cebcade..dc1ed4dd76 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -15590,8 +15590,8 @@ playground_history_command() { fzf_option_rounded="" fi - awk '!seen[$0]++' $root_folder/playground-run-history > /tmp/tmp - res=$(tac /tmp/tmp| sed '/^$/d' | fzf --margin=1%,1%,1%,1% $fzf_option_rounded --info=inline --cycle --prompt="🏰" --header="ctrl-c or esc to quit" --color="bg:-1,bg+:-1,info:#BDBB72,border:#FFFFFF,spinner:0,hl:#beb665,fg:#00f7f7,header:#5CC9F5,fg+:#beb665,pointer:#E12672,marker:#5CC9F5,prompt:#98BEDE" --delimiter "kafka-docker-playground" --with-nth "2,3,4" $fzf_option_wrap $fzf_option_pointer) + #awk '!seen[$0]++' $root_folder/playground-run-history > /tmp/tmp + res=$(tac $root_folder/playground-run-history | sed '/^$/d' | fzf --margin=1%,1%,1%,1% $fzf_option_rounded --info=inline --cycle --prompt="🏰" --header="ctrl-c or esc to quit" --color="bg:-1,bg+:-1,info:#BDBB72,border:#FFFFFF,spinner:0,hl:#beb665,fg:#00f7f7,header:#5CC9F5,fg+:#beb665,pointer:#E12672,marker:#5CC9F5,prompt:#98BEDE" --delimiter "kafka-docker-playground" --with-nth "2,3,4" $fzf_option_wrap $fzf_option_pointer) # Prompt the user to edit the res variable read -e -p "" -i "$res" edited_res diff --git a/scripts/cli/src/commands/history.sh b/scripts/cli/src/commands/history.sh index c5f300fe3f..ef69f63eca 100644 --- a/scripts/cli/src/commands/history.sh +++ b/scripts/cli/src/commands/history.sh @@ -17,18 +17,15 @@ else fzf_option_rounded="" fi -awk '!seen[$0]++' $root_folder/playground-run-history > /tmp/tmp -res=$(tac /tmp/tmp| sed '/^$/d' | fzf --margin=1%,1%,1%,1% $fzf_option_rounded --info=inline --cycle --prompt="🏰" --header="ctrl-c or esc to quit" --color="bg:-1,bg+:-1,info:#BDBB72,border:#FFFFFF,spinner:0,hl:#beb665,fg:#00f7f7,header:#5CC9F5,fg+:#beb665,pointer:#E12672,marker:#5CC9F5,prompt:#98BEDE" --delimiter "kafka-docker-playground" --with-nth "2,3,4" $fzf_option_wrap $fzf_option_pointer) +res=$(tac $root_folder/playground-run-history | sed '/^$/d' | fzf --margin=1%,1%,1%,1% $fzf_option_rounded --info=inline --cycle --prompt="🏰" --header="ctrl-c or esc to quit" --color="bg:-1,bg+:-1,info:#BDBB72,border:#FFFFFF,spinner:0,hl:#beb665,fg:#00f7f7,header:#5CC9F5,fg+:#beb665,pointer:#E12672,marker:#5CC9F5,prompt:#98BEDE" --delimiter "kafka-docker-playground" --with-nth "2,3,4" $fzf_option_wrap $fzf_option_pointer) # Prompt the user to edit the res variable read -e -p "" -i "$res" edited_res # Use the edited value if it is not empty -if [[ -n "$edited_res" ]]; then +if [[ -n "$edited_res" ]] +then res="$edited_res" fi -# log "🚀 Are you sure you want to run:" -# echo "$res" -#check_if_continue $res \ No newline at end of file From 1b739cb10638731690d0335b8c8aed885d439112 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Mar 2025 09:30:39 +0100 Subject: [PATCH 279/659] 3.5.5 --- connect/connect-iceberg-sink/spark/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connect/connect-iceberg-sink/spark/Dockerfile b/connect/connect-iceberg-sink/spark/Dockerfile index 88c638cbf6..e3d1b87f4c 100644 --- a/connect/connect-iceberg-sink/spark/Dockerfile +++ b/connect/connect-iceberg-sink/spark/Dockerfile @@ -48,7 +48,7 @@ ENV PYTHONPATH=$SPARK_HOME/python:$SPARK_HOME/python/lib/py4j-0.10.9.7-src.zip:$ WORKDIR ${SPARK_HOME} -ENV SPARK_VERSION=3.5.4 +ENV SPARK_VERSION=3.5.5 ENV SPARK_MAJOR_VERSION=3.5 ENV ICEBERG_VERSION=1.5.0 From 2b57bb4bb8b378a6c5bdea2fa3fe2c49cb8ff40d Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Mar 2025 09:38:45 +0100 Subject: [PATCH 280/659] remove dups --- scripts/cli/playground | 19 +++++++++++++------ scripts/cli/src/commands/history.sh | 12 +++++++++++- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index dc1ed4dd76..e8e880f72b 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -15590,20 +15590,27 @@ playground_history_command() { fzf_option_rounded="" fi - #awk '!seen[$0]++' $root_folder/playground-run-history > /tmp/tmp - res=$(tac $root_folder/playground-run-history | sed '/^$/d' | fzf --margin=1%,1%,1%,1% $fzf_option_rounded --info=inline --cycle --prompt="🏰" --header="ctrl-c or esc to quit" --color="bg:-1,bg+:-1,info:#BDBB72,border:#FFFFFF,spinner:0,hl:#beb665,fg:#00f7f7,header:#5CC9F5,fg+:#beb665,pointer:#E12672,marker:#5CC9F5,prompt:#98BEDE" --delimiter "kafka-docker-playground" --with-nth "2,3,4" $fzf_option_wrap $fzf_option_pointer) + tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) + if [ -z "$PG_VERBOSE_MODE" ] + then + trap 'rm -rf $tmp_dir' EXIT + else + log "🐛📂 not deleting tmp dir $tmp_dir" + fi + + tac $root_folder/playground-run-history > $tmp_dir/tmp + awk '!seen[$0]++' $tmp_dir/tmp > $tmp_dir/tmp2 + res=$(cat $tmp_dir/tmp2 | sed '/^$/d' | fzf --margin=1%,1%,1%,1% $fzf_option_rounded --info=inline --cycle --prompt="🏰" --header="ctrl-c or esc to quit" --color="bg:-1,bg+:-1,info:#BDBB72,border:#FFFFFF,spinner:0,hl:#beb665,fg:#00f7f7,header:#5CC9F5,fg+:#beb665,pointer:#E12672,marker:#5CC9F5,prompt:#98BEDE" --delimiter "kafka-docker-playground" --with-nth "2,3,4" $fzf_option_wrap $fzf_option_pointer) # Prompt the user to edit the res variable read -e -p "" -i "$res" edited_res # Use the edited value if it is not empty - if [[ -n "$edited_res" ]]; then + if [[ -n "$edited_res" ]] + then res="$edited_res" fi - # log "🚀 Are you sure you want to run:" - # echo "$res" - #check_if_continue $res } diff --git a/scripts/cli/src/commands/history.sh b/scripts/cli/src/commands/history.sh index ef69f63eca..5a1b0f0cda 100644 --- a/scripts/cli/src/commands/history.sh +++ b/scripts/cli/src/commands/history.sh @@ -17,7 +17,17 @@ else fzf_option_rounded="" fi -res=$(tac $root_folder/playground-run-history | sed '/^$/d' | fzf --margin=1%,1%,1%,1% $fzf_option_rounded --info=inline --cycle --prompt="🏰" --header="ctrl-c or esc to quit" --color="bg:-1,bg+:-1,info:#BDBB72,border:#FFFFFF,spinner:0,hl:#beb665,fg:#00f7f7,header:#5CC9F5,fg+:#beb665,pointer:#E12672,marker:#5CC9F5,prompt:#98BEDE" --delimiter "kafka-docker-playground" --with-nth "2,3,4" $fzf_option_wrap $fzf_option_pointer) +tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) +if [ -z "$PG_VERBOSE_MODE" ] +then + trap 'rm -rf $tmp_dir' EXIT +else + log "🐛📂 not deleting tmp dir $tmp_dir" +fi + +tac $root_folder/playground-run-history > $tmp_dir/tmp +awk '!seen[$0]++' $tmp_dir/tmp > $tmp_dir/tmp2 +res=$(cat $tmp_dir/tmp2 | sed '/^$/d' | fzf --margin=1%,1%,1%,1% $fzf_option_rounded --info=inline --cycle --prompt="🏰" --header="ctrl-c or esc to quit" --color="bg:-1,bg+:-1,info:#BDBB72,border:#FFFFFF,spinner:0,hl:#beb665,fg:#00f7f7,header:#5CC9F5,fg+:#beb665,pointer:#E12672,marker:#5CC9F5,prompt:#98BEDE" --delimiter "kafka-docker-playground" --with-nth "2,3,4" $fzf_option_wrap $fzf_option_pointer) # Prompt the user to edit the res variable read -e -p "" -i "$res" edited_res From b0db52ddc2e7ba97486a88646fcd811feb1b286f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Mar 2025 09:52:08 +0100 Subject: [PATCH 281/659] fix --- .../connect-onprem-to-cloud-avro.sh | 82 ++++++++----------- 1 file changed, 32 insertions(+), 50 deletions(-) diff --git a/ccloud/replicator/connect-onprem-to-cloud-avro.sh b/ccloud/replicator/connect-onprem-to-cloud-avro.sh index 6a4344887b..bead956137 100755 --- a/ccloud/replicator/connect-onprem-to-cloud-avro.sh +++ b/ccloud/replicator/connect-onprem-to-cloud-avro.sh @@ -18,61 +18,43 @@ playground topic create --topic products-avro set -e log "Sending messages to topic products-avro on source OnPREM cluster" -playground topic produce -t products-avro --nb-messages 3 << 'EOF' -{ - "fields": [ - { - "name": "id", - "type": "int" - }, - { - "name": "product", - "type": "string" - }, - { - "name": "quantity", - "type": "int" - }, - { - "name": "price", - "type": "float" - } - ], - "name": "myrecord", - "type": "record" -} +docker exec -i connect kafka-avro-console-producer --broker-list broker:9092 --property schema.registry.url=http://schema-registry:8081 --topic products-avro --property value.schema='{"type":"record","name":"myrecord","fields":[{"name":"name","type":"string"}, +{"name":"price", "type": "float"}, {"name":"quantity", "type": "int"}]}' << EOF +{"name": "scissors", "price": 2.75, "quantity": 3} +{"name": "tape", "price": 0.99, "quantity": 10} +{"name": "notebooks", "price": 1.99, "quantity": 5} EOF playground connector create-or-update --connector replicate-onprem-to-cloud << EOF { - "connector.class":"io.confluent.connect.replicator.ReplicatorSourceConnector", - "src.consumer.group.id": "replicate-onprem-to-cloud", - "src.value.converter": "io.confluent.connect.avro.AvroConverter", - "src.value.converter.schema.registry.url": "http://schema-registry:8081", - "src.kafka.bootstrap.servers": "broker:9092", + "connector.class":"io.confluent.connect.replicator.ReplicatorSourceConnector", + "src.consumer.group.id": "replicate-onprem-to-cloud", + "src.value.converter": "io.confluent.connect.avro.AvroConverter", + "src.value.converter.schema.registry.url": "http://schema-registry:8081", + "src.kafka.bootstrap.servers": "broker:9092", - "value.converter": "io.confluent.connect.avro.AvroConverter", - "value.converter.schema.registry.url": "$SCHEMA_REGISTRY_URL", - "value.converter.basic.auth.user.info": "\${file:/datacloud:schema.registry.basic.auth.user.info}", - "value.converter.basic.auth.credentials.source": "USER_INFO", + "value.converter": "io.confluent.connect.avro.AvroConverter", + "value.converter.schema.registry.url": "$SCHEMA_REGISTRY_URL", + "value.converter.basic.auth.user.info": "\${file:/datacloud:schema.registry.basic.auth.user.info}", + "value.converter.basic.auth.credentials.source": "USER_INFO", - "dest.kafka.ssl.endpoint.identification.algorithm":"https", - "dest.kafka.bootstrap.servers": "\${file:/datacloud:bootstrap.servers}", - "dest.kafka.security.protocol" : "SASL_SSL", - "dest.kafka.sasl.jaas.config": "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/datacloud:sasl.username}\" password=\"\${file:/datacloud:sasl.password}\";", - "dest.kafka.sasl.mechanism":"PLAIN", - "dest.kafka.request.timeout.ms":"20000", - "dest.kafka.retry.backoff.ms":"500", - "confluent.topic.ssl.endpoint.identification.algorithm" : "https", - "confluent.topic.sasl.mechanism" : "PLAIN", - "confluent.topic.bootstrap.servers": "\${file:/datacloud:bootstrap.servers}", - "confluent.topic.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/datacloud:sasl.username}\" password=\"\${file:/datacloud:sasl.password}\";", - "confluent.topic.security.protocol" : "SASL_SSL", - "confluent.topic.replication.factor": "3", - "provenance.header.enable": true, - "topic.whitelist": "products-avro", - "topic.config.sync": false, - "topic.auto.create": false + "dest.kafka.ssl.endpoint.identification.algorithm":"https", + "dest.kafka.bootstrap.servers": "\${file:/datacloud:bootstrap.servers}", + "dest.kafka.security.protocol" : "SASL_SSL", + "dest.kafka.sasl.jaas.config": "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/datacloud:sasl.username}\" password=\"\${file:/datacloud:sasl.password}\";", + "dest.kafka.sasl.mechanism":"PLAIN", + "dest.kafka.request.timeout.ms":"20000", + "dest.kafka.retry.backoff.ms":"500", + "confluent.topic.ssl.endpoint.identification.algorithm" : "https", + "confluent.topic.sasl.mechanism" : "PLAIN", + "confluent.topic.bootstrap.servers": "\${file:/datacloud:bootstrap.servers}", + "confluent.topic.sasl.jaas.config" : "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"\${file:/datacloud:sasl.username}\" password=\"\${file:/datacloud:sasl.password}\";", + "confluent.topic.security.protocol" : "SASL_SSL", + "confluent.topic.replication.factor": "3", + "provenance.header.enable": true, + "topic.whitelist": "products-avro", + "topic.config.sync": false, + "topic.auto.create": false } EOF @@ -80,4 +62,4 @@ EOF # "value.converter.connect.meta.data": false log "Verify we have received the data in products-avro topic" -playground topic consume --topic products-avro --min-expected-messages 3 --timeout 60 +playground topic consume --topic products-avro --min-expected-messages 3 --timeout 300 From 16b82422e0c13244c8a31db6194cfafe09b50a5b Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 6 Mar 2025 15:33:17 +0100 Subject: [PATCH 282/659] retry if invalid response --- scripts/cli/confluent-hub-plugin-list.txt | 23 +++ scripts/cli/confluent-kafka-region-list.txt | 202 ++++++++++---------- scripts/cli/playground | 2 +- scripts/cli/src/lib/utils_function.sh | 2 +- 4 files changed, 126 insertions(+), 103 deletions(-) diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index b4026d5d10..942fa051d1 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -15,6 +15,29 @@ cjmatta/kafka-connect-irc cjmatta/kafka-connect-sse clickhouse/clickhouse-kafka-connect cockroachdb/cockroach-cdc +confluentinc/AlloyDbSink +confluentinc/AzureLogAnalyticsSink +confluentinc/BigQueryStorageSink +confluentinc/DynamoDbCdcSource +confluentinc/GoogleCloudFunctionsGen2Sink +confluentinc/HttpSinkV2 +confluentinc/HttpSourceV2 +confluentinc/MicrosoftSqlServerSink +confluentinc/MicrosoftSqlServerSource +confluentinc/MySqlSink +confluentinc/MySqlSource +confluentinc/OpenSearchSink +confluentinc/OracleDatabaseSink +confluentinc/OracleDatabaseSource +confluentinc/PostgresSink +confluentinc/PostgresSource +confluentinc/SalesforceBulkApiV2Sink +confluentinc/SalesforceBulkApiV2Source +confluentinc/SalesforceCdcSource +confluentinc/SalesforcePlatformEventSink +confluentinc/SalesforcePlatformEventSource +confluentinc/SalesforcePushTopicSource +confluentinc/SalesforceSObjectSink confluentinc/connect-transforms confluentinc/csid-secrets-provider-aws confluentinc/csid-secrets-provider-azure diff --git a/scripts/cli/confluent-kafka-region-list.txt b/scripts/cli/confluent-kafka-region-list.txt index 69848f3e6f..4cdd63ac7e 100644 --- a/scripts/cli/confluent-kafka-region-list.txt +++ b/scripts/cli/confluent-kafka-region-list.txt @@ -1,101 +1,101 @@ -Name/Region -Bahrain(me-south-1)/me-south-1 -Belgium(europe-west1)/europe-west1 -Calgary(ca-west-1)/ca-west-1 -Canada(ca-central-1)/ca-central-1 -CapeTown(af-south-1)/af-south-1 -Dallas(us-south1)/us-south1 -Dammam(me-central2)/me-central2 -Delhi(asia-south2)/asia-south2 -Doha(me-central1)/me-central1 -Doha(qatarcentral)/qatarcentral -Dubai(uaenorth)/uaenorth -Finland(europe-north1)/europe-north1 -Frankfurt(eu-central-1)/eu-central-1 -Frankfurt(europe-west3)/europe-west3 -Frankfurt(germanywestcentral)/germanywestcentral -Gävle(swedencentral)/swedencentral -HongKong(ap-east-1)/ap-east-1 -HongKong(asia-east2)/asia-east2 -HongKong(eastasia)/eastasia -Hyderabad(ap-south-2)/ap-south-2 -Iowa(centralus)/centralus -Iowa(us-central1)/us-central1 -Ireland(eu-west-1)/eu-west-1 -Ireland(northeurope)/northeurope -Jakarta(ap-southeast-3)/ap-southeast-3 -Jakarta(asia-southeast2)/asia-southeast2 -Johannesburg/southafricanorth -(southafricanorth)/ -LasVegas(us-west4)/us-west4 -London(eu-west-2)/eu-west-2 -London(europe-west2)/europe-west2 -London(uksouth)/uksouth -LosAngeles(us-west2)/us-west2 -Madrid(europe-southwest1)/europe-southwest1 -Melbourne(ap-southeast-4)/ap-southeast-4 -Melbourne/australia-southeast2 -(australia-southeast2)/ -MexicoCentral(mexicocentral)/mexicocentral -Milan(eu-south-1)/eu-south-1 -Milan(europe-west8)/europe-west8 -Milan(italynorth)/italynorth -Montreal/northamerica-northeast1 -(northamerica-northeast1)/ -Mumbai(ap-south-1)/ap-south-1 -Mumbai(asia-south1)/asia-south1 -N.Virginia(us-east-1)/us-east-1 -N.Virginia(us-east4)/us-east4 -Netherlands(europe-west4)/europe-west4 -Netherlands(westeurope)/westeurope -NewSouthWales/australiaeast -(australiaeast)/ -NewZealandNorth/newzealandnorth -(newzealandnorth)/ -Ohio(us-east-2)/us-east-2 -Oregon(us-west-2)/us-west-2 -Oregon(us-west1)/us-west1 -Osaka(ap-northeast-3)/ap-northeast-3 -Osaka(asia-northeast2)/asia-northeast2 -Oslo(norwayeast)/norwayeast -Paris(eu-west-3)/eu-west-3 -Paris(europe-west9)/europe-west9 -Paris(francecentral)/francecentral -Phoenix(westus3)/westus3 -Pune(centralindia)/centralindia -S.Carolina(us-east1)/us-east1 -SaltLakeCity(us-west3)/us-west3 -Santiago(southamerica-west1)/southamerica-west1 -SaoPaulo(southamerica-east1)/southamerica-east1 -SaoPaulostate(brazilsouth)/brazilsouth -Seoul(ap-northeast-2)/ap-northeast-2 -Seoul(asia-northeast3)/asia-northeast3 -Seoul(koreacentral)/koreacentral -Singapore(ap-southeast-1)/ap-southeast-1 -Singapore(asia-southeast1)/asia-southeast1 -Singapore(southeastasia)/southeastasia -Spain(eu-south-2)/eu-south-2 -Spain(spaincentral)/spaincentral -Stockholm(eu-north-1)/eu-north-1 -Sydney(ap-southeast-2)/ap-southeast-2 -Sydney(australia-southeast1)/australia-southeast1 -SãoPaulo(sa-east-1)/sa-east-1 -Taiwan(asia-east1)/asia-east1 -TelAviv(il-central-1)/il-central-1 -TelAviv(me-west1)/me-west1 -Texas(southcentralus)/southcentralus -Tokyo(ap-northeast-1)/ap-northeast-1 -Tokyo(asia-northeast1)/asia-northeast1 -Tokyo(japaneast)/japaneast -Toronto(canadacentral)/canadacentral -Toronto/northamerica-northeast2 -(northamerica-northeast2)/ -Turin(europe-west12)/europe-west12 -UAE(me-central-1)/me-central-1 -Virginia(eastus)/eastus -Virginia(eastus2)/eastus2 -Warsaw(europe-central2)/europe-central2 -Washington(westus2)/westus2 -Zurich(eu-central-2)/eu-central-2 -Zurich(europe-west6)/europe-west6 -Zurich(switzerlandnorth)/switzerlandnorth +Name/Region +Bahrain(me-south-1)/me-south-1 +Belgium(europe-west1)/europe-west1 +Calgary(ca-west-1)/ca-west-1 +Canada(ca-central-1)/ca-central-1 +CapeTown(af-south-1)/af-south-1 +Dallas(us-south1)/us-south1 +Dammam(me-central2)/me-central2 +Delhi(asia-south2)/asia-south2 +Doha(me-central1)/me-central1 +Doha(qatarcentral)/qatarcentral +Dubai(uaenorth)/uaenorth +Finland(europe-north1)/europe-north1 +Frankfurt(eu-central-1)/eu-central-1 +Frankfurt(europe-west3)/europe-west3 +Frankfurt(germanywestcentral)/germanywestcentral +Gävle(swedencentral)/swedencentral +HongKong(ap-east-1)/ap-east-1 +HongKong(asia-east2)/asia-east2 +HongKong(eastasia)/eastasia +Hyderabad(ap-south-2)/ap-south-2 +Iowa(centralus)/centralus +Iowa(us-central1)/us-central1 +Ireland(eu-west-1)/eu-west-1 +Ireland(northeurope)/northeurope +Jakarta(ap-southeast-3)/ap-southeast-3 +Jakarta(asia-southeast2)/asia-southeast2 +Johannesburg/southafricanorth +(southafricanorth)/ +LasVegas(us-west4)/us-west4 +London(eu-west-2)/eu-west-2 +London(europe-west2)/europe-west2 +London(uksouth)/uksouth +LosAngeles(us-west2)/us-west2 +Madrid(europe-southwest1)/europe-southwest1 +Melbourne(ap-southeast-4)/ap-southeast-4 +Melbourne/australia-southeast2 +(australia-southeast2)/ +MexicoCentral(mexicocentral)/mexicocentral +Milan(eu-south-1)/eu-south-1 +Milan(europe-west8)/europe-west8 +Milan(italynorth)/italynorth +Montreal/northamerica-northeast1 +(northamerica-northeast1)/ +Mumbai(ap-south-1)/ap-south-1 +Mumbai(asia-south1)/asia-south1 +N.Virginia(us-east-1)/us-east-1 +N.Virginia(us-east4)/us-east4 +Netherlands(europe-west4)/europe-west4 +Netherlands(westeurope)/westeurope +NewSouthWales/australiaeast +(australiaeast)/ +NewZealandNorth/newzealandnorth +(newzealandnorth)/ +Ohio(us-east-2)/us-east-2 +Oregon(us-west-2)/us-west-2 +Oregon(us-west1)/us-west1 +Osaka(ap-northeast-3)/ap-northeast-3 +Osaka(asia-northeast2)/asia-northeast2 +Oslo(norwayeast)/norwayeast +Paris(eu-west-3)/eu-west-3 +Paris(europe-west9)/europe-west9 +Paris(francecentral)/francecentral +Phoenix(westus3)/westus3 +Pune(centralindia)/centralindia +S.Carolina(us-east1)/us-east1 +SaltLakeCity(us-west3)/us-west3 +Santiago(southamerica-west1)/southamerica-west1 +SaoPaulo(southamerica-east1)/southamerica-east1 +SaoPaulostate(brazilsouth)/brazilsouth +Seoul(ap-northeast-2)/ap-northeast-2 +Seoul(asia-northeast3)/asia-northeast3 +Seoul(koreacentral)/koreacentral +Singapore(ap-southeast-1)/ap-southeast-1 +Singapore(asia-southeast1)/asia-southeast1 +Singapore(southeastasia)/southeastasia +Spain(eu-south-2)/eu-south-2 +Spain(spaincentral)/spaincentral +Stockholm(eu-north-1)/eu-north-1 +Sydney(ap-southeast-2)/ap-southeast-2 +Sydney(australia-southeast1)/australia-southeast1 +SãoPaulo(sa-east-1)/sa-east-1 +Taiwan(asia-east1)/asia-east1 +TelAviv(il-central-1)/il-central-1 +TelAviv(me-west1)/me-west1 +Texas(southcentralus)/southcentralus +Tokyo(ap-northeast-1)/ap-northeast-1 +Tokyo(asia-northeast1)/asia-northeast1 +Tokyo(japaneast)/japaneast +Toronto(canadacentral)/canadacentral +Toronto/northamerica-northeast2 +(northamerica-northeast2)/ +Turin(europe-west12)/europe-west12 +UAE(me-central-1)/me-central-1 +Virginia(eastus)/eastus +Virginia(eastus2)/eastus2 +Warsaw(europe-central2)/europe-central2 +Washington(westus2)/westus2 +Zurich(eu-central-2)/eu-central-2 +Zurich(europe-west6)/europe-west6 +Zurich(switzerlandnorth)/switzerlandnorth diff --git a/scripts/cli/playground b/scripts/cli/playground index e8e880f72b..9aabdc3d59 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8705,7 +8705,7 @@ function check_if_continue() case "$choice" in y|Y ) ;; n|N ) exit 1;; - * ) logerror "invalid response <$choice>!";exit 1;; + * ) logwarn "invalid response <$choice>! Please enter y or n."; check_if_continue;; esac } diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 03cf4e9c99..2670dcc893 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -371,7 +371,7 @@ function check_if_continue() case "$choice" in y|Y ) ;; n|N ) exit 1;; - * ) logerror "invalid response <$choice>!";exit 1;; + * ) logwarn "invalid response <$choice>! Please enter y or n."; check_if_continue;; esac } From f50904ff9a6ff2d05785135ee6120b0fe58e67c3 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 7 Mar 2025 11:37:18 +0100 Subject: [PATCH 283/659] reduce CONNECT_PLUGIN_PATH to speedup testing --- connect/connect-filestream-sink/docker-compose.plaintext.yml | 2 +- connect/connect-filestream-source/docker-compose.plaintext.yml | 2 +- other/custom-smt/docker-compose.plaintext.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/connect/connect-filestream-sink/docker-compose.plaintext.yml b/connect/connect-filestream-sink/docker-compose.plaintext.yml index c840a6adac..e0781ddd10 100644 --- a/connect/connect-filestream-sink/docker-compose.plaintext.yml +++ b/connect/connect-filestream-sink/docker-compose.plaintext.yml @@ -3,4 +3,4 @@ services: connect: environment: # in newer version, it is located in /usr/share/filestream-connectors - CONNECT_PLUGIN_PATH: /usr/share/java/,/usr/share/confluent-hub-components/,/usr/share/filestream-connectors \ No newline at end of file + CONNECT_PLUGIN_PATH: /usr/share/filestream-connectors \ No newline at end of file diff --git a/connect/connect-filestream-source/docker-compose.plaintext.yml b/connect/connect-filestream-source/docker-compose.plaintext.yml index c840a6adac..e0781ddd10 100644 --- a/connect/connect-filestream-source/docker-compose.plaintext.yml +++ b/connect/connect-filestream-source/docker-compose.plaintext.yml @@ -3,4 +3,4 @@ services: connect: environment: # in newer version, it is located in /usr/share/filestream-connectors - CONNECT_PLUGIN_PATH: /usr/share/java/,/usr/share/confluent-hub-components/,/usr/share/filestream-connectors \ No newline at end of file + CONNECT_PLUGIN_PATH: /usr/share/filestream-connectors \ No newline at end of file diff --git a/other/custom-smt/docker-compose.plaintext.yml b/other/custom-smt/docker-compose.plaintext.yml index 3bb0d3d974..88bd79f099 100644 --- a/other/custom-smt/docker-compose.plaintext.yml +++ b/other/custom-smt/docker-compose.plaintext.yml @@ -5,4 +5,4 @@ services: - ../../other/custom-smt/MyCustomSMT/target/MyCustomSMT-1.0.0-SNAPSHOT-jar-with-dependencies.jar:/usr/share/filestream-connectors/lib/MyCustomSMT-1.0.0-SNAPSHOT-jar-with-dependencies.jar environment: # in newer version, it is located in /usr/share/filestream-connectors - CONNECT_PLUGIN_PATH: /usr/share/java/,/usr/share/confluent-hub-components/,/usr/share/filestream-connectors \ No newline at end of file + CONNECT_PLUGIN_PATH: /usr/share/filestream-connectors \ No newline at end of file From f52b2f44a34567f03c79de83a0165ea8fd7fd6e9 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 7 Mar 2025 14:27:48 +0100 Subject: [PATCH 284/659] update bashly --- scripts/cli/playground | 422 ++++++++++++++---- scripts/cli/playground.yaml | 16 + .../cli/src/commands/connector/show-lag.sh | 2 +- .../shell-script-command-completion/render.rb | 1 + 4 files changed, 360 insertions(+), 81 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 9aabdc3d59..37745c02c9 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# This script was generated by bashly 1.2.3 (https://bashly.dannyb.co) +# This script was generated by bashly 1.2.10 (https://bashly.dev) # Modifying it manually is not recommended # :wrapper.bash3_bouncer @@ -12830,6 +12830,7 @@ validate_percentage() { # :command.command_functions # :command.function playground_help_command() { + # src/commands/help.sh command="${args[command]}" long_usage=yes @@ -12854,6 +12855,7 @@ playground_help_command() { # :command.function playground_status_command() { + # src/commands/status.sh test_file=$(playground state get run.test_file) @@ -12897,12 +12899,14 @@ playground_status_command() { # :command.function playground_get_docker_ports_command() { + # src/commands/get-docker-ports.sh docker ps --format '{{.Ports}}' | tr ',' '\n' | awk -F '->' '{print $1}' | cut -d':' -f2 | tr -d '/tcp' | tr -d ' ' | awk '!/-/' | sort -n | uniq } # :command.function playground_get_connector_list_command() { + # src/commands/get-connector-list.sh connector_type=$(playground state get run.connector_type) @@ -12920,6 +12924,7 @@ playground_get_connector_list_command() { # :command.function playground_get_ec2_instance_list_command() { + # src/commands/get-ec2-instance-list.sh cur="${args[cur]}" @@ -12928,6 +12933,7 @@ playground_get_ec2_instance_list_command() { # :command.function playground_get_ec2_cloudformation_list_command() { + # src/commands/get-ec2-cloudformation-list.sh cur="${args[cur]}" @@ -12936,18 +12942,21 @@ playground_get_ec2_cloudformation_list_command() { # :command.function playground_get_zazkia_connection_list_command() { + # src/commands/get-zazkia-connection-list.sh get_zazkia_id_list } # :command.function playground_generate_fzf_find_files_command() { + # src/commands/generate-fzf-find-files.sh generate_fzf_find_files } # :command.function playground_generate_tag_list_command() { + # src/commands/generate-tag-list.sh function listAllTags() { @@ -12975,6 +12984,7 @@ playground_generate_tag_list_command() { # :command.function playground_generate_connector_plugin_list_command() { + # src/commands/generate-connector-plugin-list.sh curl -s -S 'https://api.hub.confluent.io/api/plugins?per_page=100000' | jq '. | sort_by(.release_date) | reverse | .' > /tmp/allmanis.json @@ -12985,6 +12995,7 @@ playground_generate_connector_plugin_list_command() { # :command.function playground_generate_kafka_region_list_command() { + # src/commands/generate-kafka-region-list.sh confluent kafka region list | awk -F'|' '{print $1"/"$3}' | sed 's/[[:blank:]]//g' | grep -v "CloudID" | grep -v "\-\-\-" | grep -v '^/' > $root_folder/scripts/cli/confluent-kafka-region-list.txt @@ -12992,6 +13003,7 @@ playground_generate_kafka_region_list_command() { # :command.function playground_get_connector_plugin_command() { + # src/commands/get-connector-plugin.sh cur="${args[cur]}" @@ -13000,6 +13012,7 @@ playground_get_connector_plugin_command() { # :command.function playground_get_ccloud_environment_list_command() { + # src/commands/get-ccloud-environment-list.sh cur="${args[cur]}" @@ -13008,6 +13021,7 @@ playground_get_ccloud_environment_list_command() { # :command.function playground_get_ccloud_cluster_list_command() { + # src/commands/get-ccloud-cluster-list.sh cur="${args[cur]}" @@ -13016,6 +13030,7 @@ playground_get_ccloud_cluster_list_command() { # :command.function playground_get_tag_list_command() { + # src/commands/get-tag-list.sh cur="${args[cur]}" @@ -13024,6 +13039,7 @@ playground_get_tag_list_command() { # :command.function playground_get_kafka_region_list_command() { + # src/commands/get-kafka-region-list.sh cur="${args[cur]}" @@ -13032,6 +13048,7 @@ playground_get_kafka_region_list_command() { # :command.function playground_get_topic_list_command() { + # src/commands/get-topic-list.sh skip_connect_internal_topics="${args[--skip-connect-internal-topics]}" @@ -13067,6 +13084,7 @@ playground_get_topic_list_command() { # :command.function playground_get_subject_list_command() { + # src/commands/get-subject-list.sh get_sr_url_and_security deleted="${args[--deleted]}" @@ -13081,6 +13099,7 @@ playground_get_subject_list_command() { # :command.function playground_get_examples_list_with_fzf_command() { + # src/commands/get-examples-list-with-fzf.sh without_repro="${args[--without-repro]}" sink_only="${args[--sink-only]}" @@ -13227,6 +13246,7 @@ playground_get_examples_list_with_fzf_command() { # :command.function playground_get_zip_or_jar_with_fzf_command() { + # src/commands/get-zip-or-jar-with-fzf.sh cur="${args[cur]}" type="${args[--type]}" @@ -13236,6 +13256,7 @@ playground_get_zip_or_jar_with_fzf_command() { # :command.function playground_get_specific_file_extension_command() { + # src/commands/get-specific-file-extension.sh cur="${args[cur]}" extension="${args[--extension]}" @@ -13245,6 +13266,7 @@ playground_get_specific_file_extension_command() { # :command.function playground_get_any_file_with_fzf_command() { + # src/commands/get-any-file-with-fzf.sh cur="${args[cur]}" @@ -13254,6 +13276,7 @@ playground_get_any_file_with_fzf_command() { # :command.function playground_get_playground_repro_export_with_fzf_command() { + # src/commands/get-playground-repro-export-with-fzf.sh cur="${args[cur]}" @@ -13262,6 +13285,7 @@ playground_get_playground_repro_export_with_fzf_command() { # :command.function playground_get_predefined_schemas_command() { + # src/commands/get-predefined-schemas.sh cur="${args[cur]}" @@ -13270,6 +13294,7 @@ playground_get_predefined_schemas_command() { # :command.function playground_update_readme_command() { + # src/commands/update-readme.sh tags="${args[--tags]}" generate_for_kb="${args[--generate-for-kb]}" @@ -13709,6 +13734,7 @@ playground_update_readme_command() { # :command.function playground_update_docs_command() { + # src/commands/update-docs.sh cd ${root_folder}/scripts/cli @@ -13722,6 +13748,7 @@ playground_update_docs_command() { # :command.function playground_bashly_reload_command() { + # src/commands/bashly-reload.sh cd $root_folder/scripts/cli bashly generate @@ -13732,6 +13759,7 @@ playground_bashly_reload_command() { # :command.function playground_state_show_command() { + # src/commands/state/show.sh # Using the standard library (lib/ini.sh) to show the entire config file if [ ! -f "$root_folder/playground.ini" ] @@ -13744,6 +13772,7 @@ playground_state_show_command() { # :command.function playground_state_get_command() { + # src/commands/state/get.sh # Using the standard library (lib/ini.sh) to show a value from the config if [ ! -f "$root_folder/playground.ini" ] @@ -13765,6 +13794,7 @@ playground_state_get_command() { # :command.function playground_state_set_command() { + # src/commands/state/set.sh # Using the standard library (lib/ini.sh) to store a value to the config if [ ! -f "$root_folder/playground.ini" ] @@ -13783,6 +13813,7 @@ playground_state_set_command() { # :command.function playground_state_del_command() { + # src/commands/state/del.sh # Using the standard library (lib/ini.sh) to delete a value from the config if [ ! -f "$root_folder/playground.ini" ] @@ -13801,6 +13832,7 @@ playground_state_del_command() { # :command.function playground_config_show_command() { + # src/commands/config/show.sh # Using the standard library (lib/ini.sh) to show the entire config file if [ ! -f "$root_folder/playground_config.ini" ] @@ -13815,6 +13847,7 @@ playground_config_show_command() { # :command.function playground_config_get_command() { + # src/commands/config/get.sh # Using the standard library (lib/ini.sh) to show a value from the config if [ ! -f "$root_folder/playground_config.ini" ] @@ -13839,6 +13872,7 @@ playground_config_get_command() { # :command.function playground_config_set_command() { + # src/commands/config/set.sh # Using the standard library (lib/ini.sh) to store a value to the config if [ ! -f $root_folder/playground_config.ini ] @@ -13857,6 +13891,7 @@ playground_config_set_command() { # :command.function playground_config_editor_command() { + # src/commands/config/editor.sh log "🔖 configuring editor with ${args[editor]}" playground config set editor "${args[editor]}" @@ -13864,6 +13899,7 @@ playground_config_editor_command() { # :command.function playground_config_folder_zip_or_jar_command() { + # src/commands/config/folder_zip_or_jar.sh # Convert the space delimited string to an array folders='' @@ -13881,6 +13917,7 @@ playground_config_folder_zip_or_jar_command() { # :command.function playground_config_clipboard_command() { + # src/commands/config/clipboard.sh if [[ "$OSTYPE" != "darwin"* ]] then @@ -13894,6 +13931,7 @@ playground_config_clipboard_command() { # :command.function playground_config_open_ccloud_connector_in_browser_automatically_command() { + # src/commands/config/open-ccloud-connector-in-browser/automatically.sh log "📋 configuring automatically with ${args[automatically]}" playground config set open-ccloud-connector-in-browser.automatically "${args[automatically]}" @@ -13901,6 +13939,7 @@ playground_config_open_ccloud_connector_in_browser_automatically_command() { # :command.function playground_config_open_ccloud_connector_in_browser_browser_command() { + # src/commands/config/open-ccloud-connector-in-browser/browser.sh log "🔖 configuring browser for open-ccloud-connector-in-browser with ${args[browser]}" playground config set open-ccloud-connector-in-browser.browser "${args[browser]}" @@ -13908,6 +13947,7 @@ playground_config_open_ccloud_connector_in_browser_browser_command() { # :command.function playground_config_container_kill_all_before_run_command() { + # src/commands/config/container-kill-all-before-run.sh log "📋 configuring container-kill-all-before-run with ${args[enabled]}" playground config set container-kill-all-before-run "${args[enabled]}" @@ -13915,6 +13955,7 @@ playground_config_container_kill_all_before_run_command() { # :command.function playground_config_check_repo_version_command() { + # src/commands/config/check-repo-version.sh log "📋 configuring check-repo-version with ${args[enabled]}" playground config set check-repo-version "${args[enabled]}" @@ -13922,6 +13963,7 @@ playground_config_check_repo_version_command() { # :command.function playground_run_command() { + # src/commands/run.sh DIR_CLI="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" @@ -15496,6 +15538,7 @@ playground_run_command() { # :command.function playground_re_run_command() { + # src/commands/re-run.sh test_file=$(playground state get run.test_file) @@ -15516,6 +15559,7 @@ playground_re_run_command() { # :command.function playground_get_ci_result_command() { + # src/commands/get-ci-result.sh test_file=$(playground state get run.test_file) @@ -15570,6 +15614,7 @@ playground_get_ci_result_command() { # :command.function playground_history_command() { + # src/commands/history.sh if [ ! -f $root_folder/playground-run-history ] then @@ -15616,6 +15661,7 @@ playground_history_command() { # :command.function playground_start_environment_command() { + # src/commands/start-environment.sh IGNORE_CHECK_FOR_DOCKER_COMPOSE=true @@ -15663,6 +15709,7 @@ playground_start_environment_command() { # :command.function playground_switch_ccloud_command() { + # src/commands/switch-ccloud.sh log "🌩️ switch to ccloud environment" @@ -15694,6 +15741,7 @@ playground_switch_ccloud_command() { # :command.function playground_switch_back_command() { + # src/commands/switch-back.sh environment_before_switch=$(playground state get run.environment_before_switch) if [ "$environment_before_switch" == "" ] @@ -15733,6 +15781,7 @@ playground_switch_back_command() { # :command.function playground_update_version_command() { + # src/commands/update-version.sh tag="${args[--tag]}" connector_tag="${args[--connector-tag]}" @@ -16172,6 +16221,7 @@ playground_update_version_command() { # :command.function playground_open_command() { + # src/commands/open.sh test_file="${args[--file]}" wait="${args[--wait]}" @@ -16204,6 +16254,7 @@ playground_open_command() { # :command.function playground_stop_command() { + # src/commands/stop.sh test_file=$(playground state get run.test_file) @@ -16235,6 +16286,7 @@ playground_stop_command() { # :command.function playground_remove_all_docker_images_command() { + # src/commands/remove-all-docker-images.sh log "🧨 Remove all docker images (including docker volumes)" check_if_continue @@ -16248,6 +16300,7 @@ playground_remove_all_docker_images_command() { # :command.function playground_cleanup_cloud_details_command() { + # src/commands/cleanup-cloud-details.sh if [ -d $root_folder/.ccloud ] then @@ -16266,6 +16319,7 @@ playground_cleanup_cloud_details_command() { # :command.function playground_open_docs_command() { + # src/commands/open-docs.sh only_show_url="${args[--only-show-url]}" test_file=$(playground state get run.test_file) @@ -16308,6 +16362,7 @@ playground_open_docs_command() { # :command.function playground_cleanup_cloud_resources_command() { + # src/commands/cleanup-cloud-resources.sh user="${args[--user]}" force="${args[--force]}" @@ -16630,6 +16685,7 @@ EOF # :command.function playground_repro_export_command() { + # src/commands/repro/export.sh all="${args[--all]}" @@ -16749,6 +16805,7 @@ playground_repro_export_command() { # :command.function playground_repro_import_command() { + # src/commands/repro/import.sh file="${args[--file]}" @@ -16787,6 +16844,7 @@ playground_repro_import_command() { # :command.function playground_repro_bootstrap_command() { + # src/commands/repro/bootstrap.sh IGNORE_CHECK_FOR_DOCKER_COMPOSE=true @@ -18057,6 +18115,7 @@ EOF # :command.function playground_get_docker_compose_command() { + # src/commands/get-docker-compose.sh # keep TAG, CONNECT TAG and ORACLE_IMAGE export TAG=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d ":" -f 2) @@ -18082,6 +18141,7 @@ playground_get_docker_compose_command() { # :command.function playground_schema_get_command() { + # src/commands/schema/get.sh subject="${args[--subject]}" id="${args[--id]}" @@ -18231,6 +18291,7 @@ playground_schema_get_command() { # :command.function playground_schema_register_command() { + # src/commands/schema/register.sh subject="${args[--subject]}" schema="${args[--schema]}" @@ -18434,6 +18495,7 @@ playground_schema_register_command() { # :command.function playground_schema_get_compatibility_command() { + # src/commands/schema/get-compatibility.sh subject="${args[--subject]}" verbose="${args[--verbose]}" @@ -18470,6 +18532,7 @@ playground_schema_get_compatibility_command() { # :command.function playground_schema_set_compatibility_command() { + # src/commands/schema/set-compatibility.sh subject="${args[--subject]}" compatibility="${args[--compatibility]}" @@ -18506,6 +18569,7 @@ playground_schema_set_compatibility_command() { # :command.function playground_schema_get_mode_command() { + # src/commands/schema/get-mode.sh subject="${args[--subject]}" verbose="${args[--verbose]}" @@ -18542,6 +18606,7 @@ playground_schema_get_mode_command() { # :command.function playground_schema_set_mode_command() { + # src/commands/schema/set-mode.sh subject="${args[--subject]}" mode="${args[--mode]}" @@ -18579,6 +18644,7 @@ playground_schema_set_mode_command() { # :command.function playground_schema_set_normalize_command() { + # src/commands/schema/set-normalize.sh value="${args[--value]}" verbose="${args[--verbose]}" @@ -18615,6 +18681,7 @@ playground_schema_set_normalize_command() { # :command.function playground_schema_delete_command() { + # src/commands/schema/delete.sh subject="${args[--subject]}" version="${args[--version]}" @@ -18710,6 +18777,7 @@ playground_schema_delete_command() { # :command.function playground_schema_derive_schema_command() { + # src/commands/schema/derive-schema.sh schema_type="${args[--schema-type]}" payload="${args[--payload]}" @@ -18806,6 +18874,7 @@ EOF # :command.function playground_tcp_proxy_start_command() { + # src/commands/tcp-proxy/start.sh hostname="${args[--hostname]}" port="${args[--port]}" @@ -18945,6 +19014,7 @@ EOF # :command.function playground_tcp_proxy_get_connections_command() { + # src/commands/tcp-proxy/get-connections.sh connection_id="${args[--connection-id]}" @@ -18964,6 +19034,7 @@ playground_tcp_proxy_get_connections_command() { # :command.function playground_tcp_proxy_delay_command() { + # src/commands/tcp-proxy/delay.sh delay_service_response="${args[--delay-service-response]}" connection_id="${args[--connection-id]}" @@ -18999,6 +19070,7 @@ playground_tcp_proxy_delay_command() { # :command.function playground_tcp_proxy_break_command() { + # src/commands/tcp-proxy/break.sh break_service_response="${args[--break-service-response]}" connection_id="${args[--connection-id]}" @@ -19034,6 +19106,7 @@ playground_tcp_proxy_break_command() { # :command.function playground_tcp_proxy_close_connection_command() { + # src/commands/tcp-proxy/close-connection.sh connection_id="${args[--connection-id]}" @@ -19064,6 +19137,7 @@ playground_tcp_proxy_close_connection_command() { # :command.function playground_tcp_proxy_close_all_connection_with_error_command() { + # src/commands/tcp-proxy/close-all-connection-with-error.sh log "🧹 Close all Zazkia TCP connections which are in error state" handle_onprem_connect_rest_api "curl -o /dev/null -w '%{http_code}' -s -X POST -H \"Content-Type: application/json\" \"http://localhost:9191/links/closeAllWithError\"" @@ -19072,6 +19146,7 @@ playground_tcp_proxy_close_all_connection_with_error_command() { # :command.function playground_tcp_proxy_toggle_accept_connections_command() { + # src/commands/tcp-proxy/toggle-accept-connections.sh log "🙅‍♂️ Change whether new connections can be accepted" handle_onprem_connect_rest_api "curl -s -X POST -H \"Content-Type: application/json\" --header 'Accept: application/json' \"http://localhost:9191/routes/tcp-proxy/toggle-accept\"" @@ -19081,6 +19156,7 @@ playground_tcp_proxy_toggle_accept_connections_command() { # :command.function playground_tcp_proxy_toggle_reads_client_command() { + # src/commands/tcp-proxy/toggle-reads-client.sh connection_id="${args[--connection-id]}" @@ -19110,6 +19186,7 @@ playground_tcp_proxy_toggle_reads_client_command() { # :command.function playground_tcp_proxy_toggle_reads_service_command() { + # src/commands/tcp-proxy/toggle-reads-service.sh connection_id="${args[--connection-id]}" @@ -19139,6 +19216,7 @@ playground_tcp_proxy_toggle_reads_service_command() { # :command.function playground_tcp_proxy_toggle_writes_client_command() { + # src/commands/tcp-proxy/toggle-writes-client.sh connection_id="${args[--connection-id]}" @@ -19168,6 +19246,7 @@ playground_tcp_proxy_toggle_writes_client_command() { # :command.function playground_tcp_proxy_toggle_writes_service_command() { + # src/commands/tcp-proxy/toggle-writes-service.sh connection_id="${args[--connection-id]}" @@ -19197,6 +19276,7 @@ playground_tcp_proxy_toggle_writes_service_command() { # :command.function playground_tools_install_vscode_extension_command() { + # src/commands/tools/install-vscode-extension.sh tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) if [ -z "$PG_VERBOSE_MODE" ] @@ -19246,6 +19326,7 @@ playground_tools_install_vscode_extension_command() { # :command.function playground_tools_read_avro_file_command() { + # src/commands/tools/read-avro-file.sh file="${args[--file]}" @@ -19266,6 +19347,7 @@ playground_tools_read_avro_file_command() { # :command.function playground_tools_read_parquet_file_command() { + # src/commands/tools/read-parquet-file.sh file="${args[--file]}" @@ -19286,6 +19368,7 @@ playground_tools_read_parquet_file_command() { # :command.function playground_tools_certs_create_command() { + # src/commands/tools/certs-create.sh output_folder="${args[--output-folder]}" verbose="${args[--verbose]}" @@ -19321,6 +19404,7 @@ playground_tools_certs_create_command() { # :command.function playground_debug_enable_remote_debugging_command() { + # src/commands/debug/enable-remote-debugging.sh container="${args[--container]}" @@ -19352,6 +19436,7 @@ playground_debug_enable_remote_debugging_command() { # :command.function playground_debug_testssl_command() { + # src/commands/debug/testssl.sh arguments="${args[arguments]}" @@ -19361,6 +19446,7 @@ playground_debug_testssl_command() { # :command.function playground_debug_generate_diagnostics_command() { + # src/commands/debug/generate-diagnostics.sh container="${args[--container]}" tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) @@ -19411,6 +19497,7 @@ playground_debug_generate_diagnostics_command() { # :command.function playground_debug_thread_dump_command() { + # src/commands/debug/thread-dump.sh container="${args[--container]}" filename="/tmp/thread-dump-$container-`date '+%Y-%m-%d-%H-%M-%S'`.log" @@ -19435,6 +19522,7 @@ playground_debug_thread_dump_command() { # :command.function playground_debug_heap_dump_command() { + # src/commands/debug/heap-dump.sh container="${args[--container]}" live="${args[--live]}" @@ -19490,6 +19578,7 @@ playground_debug_heap_dump_command() { # :command.function playground_debug_tcp_dump_command() { + # src/commands/debug/tcp-dump.sh container="${args[--container]}" port="${args[--port]}" @@ -19557,6 +19646,7 @@ playground_debug_tcp_dump_command() { # :command.function playground_debug_block_traffic_command() { + # src/commands/debug/block-traffic.sh container="${args[--container]}" port="${args[--port]}" @@ -19669,6 +19759,7 @@ playground_debug_block_traffic_command() { # :command.function playground_debug_java_debug_command() { + # src/commands/debug/java-debug.sh container="${args[--container]}" type="${args[--type]}" @@ -19699,6 +19790,7 @@ playground_debug_java_debug_command() { # :command.function playground_debug_flight_recorder_command() { + # src/commands/debug/flight-recorder.sh container="${args[--container]}" action="${args[--action]}" @@ -19782,6 +19874,7 @@ playground_debug_flight_recorder_command() { # :command.function playground_debug_log_level_get_command() { + # src/commands/debug/log-level/get.sh get_connect_url_and_security @@ -19799,6 +19892,7 @@ playground_debug_log_level_get_command() { # :command.function playground_debug_log_level_set_command() { + # src/commands/debug/log-level/set.sh get_connect_url_and_security @@ -19826,6 +19920,7 @@ playground_debug_log_level_set_command() { # :command.function playground_get_jmx_metrics_command() { + # src/commands/get-jmx-metrics.sh IGNORE_CHECK_FOR_DOCKER_COMPOSE=true @@ -19847,6 +19942,7 @@ playground_get_jmx_metrics_command() { # :command.function playground_container_get_properties_command() { + # src/commands/container/get-properties.sh container="${args[--container]}" @@ -19866,6 +19962,7 @@ EOF # :command.function playground_container_recreate_command() { + # src/commands/container/recreate.sh ignore_current_versions="${args[--ignore-current-versions]}" @@ -19917,6 +20014,7 @@ playground_container_recreate_command() { # :command.function playground_container_get_ip_addresses_command() { + # src/commands/container/get-ip-addresses.sh log "Get IP address of running containers" docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq) @@ -19924,6 +20022,7 @@ playground_container_get_ip_addresses_command() { # :command.function playground_container_kill_all_command() { + # src/commands/container/kill-all.sh log "💀 kill all docker containers" docker rm -f $(docker ps -qa) > /dev/null 2>&1 @@ -19931,6 +20030,7 @@ playground_container_kill_all_command() { # :command.function playground_container_logs_command() { + # src/commands/container/logs.sh container="${args[--container]}" open="${args[--open]}" @@ -19958,6 +20058,7 @@ playground_container_logs_command() { # :command.function playground_container_ssh_command() { + # src/commands/container/ssh.sh container="${args[--container]}" shell="${args[--shell]}" @@ -19967,6 +20068,7 @@ playground_container_ssh_command() { # :command.function playground_container_change_jdk_command() { + # src/commands/container/change-jdk.sh container="${args[--container]}" version="${args[--version]}" @@ -19994,6 +20096,7 @@ playground_container_change_jdk_command() { # :command.function playground_container_exec_command() { + # src/commands/container/exec.sh container="${args[--container]}" command="${args[--command]}" @@ -20012,6 +20115,7 @@ playground_container_exec_command() { # :command.function playground_container_restart_command() { + # src/commands/container/restart.sh container="${args[--container]}" @@ -20026,6 +20130,7 @@ playground_container_restart_command() { # :command.function playground_container_pause_command() { + # src/commands/container/pause.sh container="${args[--container]}" @@ -20035,6 +20140,7 @@ playground_container_pause_command() { # :command.function playground_container_resume_command() { + # src/commands/container/resume.sh container="${args[--container]}" @@ -20044,6 +20150,7 @@ playground_container_resume_command() { # :command.function playground_container_kill_command() { + # src/commands/container/kill.sh container="${args[--container]}" @@ -20053,6 +20160,7 @@ playground_container_kill_command() { # :command.function playground_container_set_environment_variables_command() { + # src/commands/container/set-environment-variables.sh container="${args[--container]}" restore_original_values="${args[--restore-original-values]}" @@ -20130,6 +20238,7 @@ EOF # :command.function playground_container_wait_for_connect_rest_api_ready_command() { + # src/commands/container/wait-for-connect-rest-api-ready.sh max_wait="${args[--max-wait]}" @@ -20150,6 +20259,7 @@ playground_container_wait_for_connect_rest_api_ready_command() { # :command.function playground_topic_get_number_records_command() { + # src/commands/topic/get-number-records.sh topic="${args[--topic]}" @@ -20269,6 +20379,7 @@ playground_topic_get_number_records_command() { # :command.function playground_topic_display_consumer_offsets_command() { + # src/commands/topic/display-consumer-offsets.sh get_security_broker "--consumer.config" get_environment_used @@ -20292,6 +20403,7 @@ playground_topic_display_consumer_offsets_command() { # :command.function playground_topic_list_command() { + # src/commands/topic/list.sh log "🔘 List of topics (internal topics are excluded)" playground get-topic-list --skip-connect-internal-topics @@ -20299,6 +20411,7 @@ playground_topic_list_command() { # :command.function playground_topic_describe_command() { + # src/commands/topic/describe.sh topic="${args[--topic]}" verbose="${args[--verbose]}" @@ -20359,6 +20472,7 @@ playground_topic_describe_command() { # :command.function playground_topic_set_schema_compatibility_command() { + # src/commands/topic/set-schema-compatibility.sh topic="${args[--topic]}" compatibility="${args[--compatibility]}" @@ -20394,6 +20508,7 @@ playground_topic_set_schema_compatibility_command() { # :command.function playground_topic_consume_command() { + # src/commands/topic/consume.sh topic="${args[--topic]}" verbose="${args[--verbose]}" @@ -20925,6 +21040,7 @@ playground_topic_consume_command() { # :command.function playground_topic_produce_command() { + # src/commands/topic/produce.sh topic="${args[--topic]}" verbose="${args[--verbose]}" @@ -22207,6 +22323,7 @@ playground_topic_produce_command() { # :command.function playground_topic_create_command() { + # src/commands/topic/create.sh topic="${args[--topic]}" nb_partitions="${args[--nb-partitions]}" @@ -22262,6 +22379,7 @@ playground_topic_create_command() { # :command.function playground_topic_delete_command() { + # src/commands/topic/delete.sh topic="${args[--topic]}" verbose="${args[--verbose]}" @@ -22337,6 +22455,7 @@ playground_topic_delete_command() { # :command.function playground_topic_alter_command() { + # src/commands/topic/alter.sh topic="${args[--topic]}" @@ -22384,6 +22503,7 @@ playground_topic_alter_command() { # :command.function playground_connector_plugin_search_jar_command() { + # src/commands/connector-plugin/search-jar.sh connector_plugin="${args[--connector-plugin]}" connector_tag="${args[--connector-tag]}" @@ -22446,6 +22566,7 @@ playground_connector_plugin_search_jar_command() { # :command.function playground_connector_plugin_versions_command() { + # src/commands/connector-plugin/versions.sh connector_plugin="${args[--connector-plugin]}" last="${args[--last]}" @@ -22568,6 +22689,7 @@ playground_connector_plugin_versions_command() { # :command.function playground_connector_status_command() { + # src/commands/connector/status.sh connector="${args[--connector]}" verbose="${args[--verbose]}" @@ -22743,6 +22865,7 @@ playground_connector_status_command() { # :command.function playground_connector_offsets_get_command() { + # src/commands/connector/offsets/get.sh connector="${args[--connector]}" verbose="${args[--verbose]}" @@ -22871,6 +22994,7 @@ playground_connector_offsets_get_command() { # :command.function playground_connector_offsets_reset_command() { + # src/commands/connector/offsets/reset.sh connector="${args[--connector]}" verbose="${args[--verbose]}" @@ -23033,6 +23157,7 @@ playground_connector_offsets_reset_command() { # :command.function playground_connector_offsets_alter_command() { + # src/commands/connector/offsets/alter.sh connector="${args[--connector]}" verbose="${args[--verbose]}" @@ -23247,6 +23372,7 @@ playground_connector_offsets_alter_command() { # :command.function playground_connector_offsets_get_offsets_request_status_command() { + # src/commands/connector/offsets/get-offsets-request-status.sh connector="${args[--connector]}" verbose="${args[--verbose]}" @@ -23309,6 +23435,7 @@ playground_connector_offsets_get_offsets_request_status_command() { # :command.function playground_connector_plugins_command() { + # src/commands/connector/plugins.sh all="${args[--all]}" verbose="${args[--verbose]}" @@ -23347,6 +23474,7 @@ playground_connector_plugins_command() { # :command.function playground_connector_pause_command() { + # src/commands/connector/pause.sh connector="${args[--connector]}" verbose="${args[--verbose]}" @@ -23390,6 +23518,7 @@ playground_connector_pause_command() { # :command.function playground_connector_versions_command() { + # src/commands/connector/versions.sh test_file=$(playground state get run.test_file) @@ -23464,6 +23593,7 @@ playground_connector_versions_command() { # :command.function playground_connector_restart_command() { + # src/commands/connector/restart.sh connector="${args[--connector]}" verbose="${args[--verbose]}" @@ -23531,6 +23661,7 @@ playground_connector_restart_command() { # :command.function playground_connector_stop_command() { + # src/commands/connector/stop.sh connector="${args[--connector]}" verbose="${args[--verbose]}" @@ -23586,6 +23717,7 @@ playground_connector_stop_command() { # :command.function playground_connector_resume_command() { + # src/commands/connector/resume.sh connector="${args[--connector]}" verbose="${args[--verbose]}" @@ -23629,6 +23761,7 @@ playground_connector_resume_command() { # :command.function playground_connector_delete_command() { + # src/commands/connector/delete.sh verbose="${args[--verbose]}" connector="${args[--connector]}" @@ -23670,6 +23803,7 @@ playground_connector_delete_command() { # :command.function playground_connector_show_lag_command() { + # src/commands/connector/show-lag.sh connector="${args[--connector]}" verbose="${args[--verbose]}" @@ -23806,7 +23940,7 @@ playground_connector_show_lag_command() { function log_same() { ORANGE='\033[0;33m' NC='\033[0m' # No Color - echo -e "$ORANGE`date +"%H:%M:%S"` 🔸$@$NC" + echo -e "$ORANGE$(date +"%H:%M:%S") 🔸$@$NC" } tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) @@ -23992,6 +24126,7 @@ playground_connector_show_lag_command() { # :command.function playground_connector_show_config_command() { + # src/commands/connector/show-config.sh connector="${args[--connector]}" force_rest_endpoint="${args[--force-rest-endpoint]}" @@ -24112,6 +24247,7 @@ done # :command.function playground_connector_show_config_parameters_command() { + # src/commands/connector/show-config-parameters.sh connector="${args[--connector]}" open="${args[--open]}" @@ -24344,6 +24480,7 @@ playground_connector_show_config_parameters_command() { # :command.function playground_connector_select_config_command() { + # src/commands/connector/select-config.sh connector="${args[--connector]}" @@ -24422,6 +24559,7 @@ playground_connector_select_config_command() { # :command.function playground_connector_snippets_command() { + # src/commands/connector/snippets.sh converter=${args[--converter]} dlq=${args[--dlq]} @@ -24597,6 +24735,7 @@ playground_connector_snippets_command() { # :command.function playground_connector_open_docs_command() { + # src/commands/connector/open-docs.sh test_file=$(playground state get run.test_file) only_show_url="${args[--only-show-url]}" @@ -24668,6 +24807,7 @@ playground_connector_open_docs_command() { # :command.function playground_connector_log_level_command() { + # src/commands/connector/log-level.sh level="${args[--level]}" connector="${args[--connector]}" @@ -24725,6 +24865,7 @@ playground_connector_log_level_command() { # :command.function playground_connector_logs_command() { + # src/commands/connector/logs.sh open="${args[--open]}" log="${args[--wait-for-log]}" @@ -24810,6 +24951,7 @@ playground_connector_logs_command() { # :command.function playground_connector_open_ccloud_connector_in_browser_command() { + # src/commands/connector/open-ccloud-connector-in-browser.sh connector="${args[--connector]}" browser="${args[--browser]}" @@ -24873,6 +25015,7 @@ playground_connector_open_ccloud_connector_in_browser_command() { # :command.function playground_connector_create_or_update_command() { + # src/commands/connector/create-or-update.sh connector="${args[--connector]}" json=${args[json]} @@ -25224,6 +25367,7 @@ fi # :command.function playground_connector_update_command() { + # src/commands/connector/update.sh connector="${args[--connector]}" @@ -25303,6 +25447,7 @@ playground_connector_update_command() { # :command.function playground_ec2_create_command() { + # src/commands/ec2/create.sh suffix="${args[--suffix]}" instance_type="${args[--instance-type]}" @@ -25393,6 +25538,7 @@ playground_ec2_create_command() { # :command.function playground_ec2_delete_command() { + # src/commands/ec2/delete.sh instance="${args[--instance]}" @@ -25441,6 +25587,7 @@ playground_ec2_delete_command() { # :command.function playground_ec2_open_command() { + # src/commands/ec2/open.sh instance="${args[--instance]}" enable_sync_repro_folder="${args[--enable-sync-repro-folder]}" @@ -25501,6 +25648,7 @@ playground_ec2_open_command() { # :command.function playground_ec2_allow_my_ip_command() { + # src/commands/ec2/allow-my-ip.sh instance="${args[--instance]}" @@ -25597,6 +25745,7 @@ EOF # :command.function playground_ec2_list_command() { + # src/commands/ec2/list.sh log "🔘 listing all your ec2 instances" ec2_instance_list @@ -25604,6 +25753,7 @@ playground_ec2_list_command() { # :command.function playground_ec2_stop_command() { + # src/commands/ec2/stop.sh instance="${args[--instance]}" @@ -25653,6 +25803,7 @@ playground_ec2_stop_command() { # :command.function playground_ec2_start_command() { + # src/commands/ec2/start.sh instance="${args[--instance]}" @@ -25699,6 +25850,7 @@ playground_ec2_start_command() { # :command.function playground_ec2_status_command() { + # src/commands/ec2/status.sh instance_name="${args[--instance]}" all="${args[--all]}" @@ -25724,6 +25876,7 @@ playground_ec2_status_command() { # :command.function playground_ec2_sync_repro_folder_local_to_ec2_command() { + # src/commands/ec2/sync-repro-folder/local-to-ec2.sh instance="${args[--instance]}" @@ -25780,6 +25933,7 @@ playground_ec2_sync_repro_folder_local_to_ec2_command() { # :command.function playground_ec2_sync_repro_folder_ec2_to_local_command() { + # src/commands/ec2/sync-repro-folder/ec2-to-local.sh instance="${args[--instance]}" @@ -25881,11 +26035,17 @@ parse_requirements() { done # :command.dependencies_filter - if command -v docker >/dev/null 2>&1; then - deps['docker']="$(command -v docker | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v docker >/dev/null 2>&1; then printf "missing dependency: docker\n" >&2 - printf "%s\n" "visit https://docs.docker.com/get-docker to install" >&2 + printf "%s\n\n" "visit https://docs.docker.com/get-docker to install" >&2 + missing_deps=1 + else + deps['docker']="$(command -v docker | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -26817,11 +26977,17 @@ playground_generate_kafka_region_list_parse_requirements() { done # :command.dependencies_filter - if command -v confluent >/dev/null 2>&1; then - deps['confluent']="$(command -v confluent | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v confluent >/dev/null 2>&1; then printf "missing dependency: confluent\n" >&2 - printf "%s\n" "visit https://docs.confluent.io/confluent-cli/current/overview.html to install" >&2 + printf "%s\n\n" "visit https://docs.confluent.io/confluent-cli/current/overview.html to install" >&2 + missing_deps=1 + else + deps['confluent']="$(command -v confluent | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -27075,11 +27241,17 @@ playground_get_kafka_region_list_parse_requirements() { done # :command.dependencies_filter - if command -v confluent >/dev/null 2>&1; then - deps['confluent']="$(command -v confluent | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v confluent >/dev/null 2>&1; then printf "missing dependency: confluent\n" >&2 - printf "%s\n" "visit https://docs.confluent.io/confluent-cli/current/overview.html to install" >&2 + printf "%s\n\n" "visit https://docs.confluent.io/confluent-cli/current/overview.html to install" >&2 + missing_deps=1 + else + deps['confluent']="$(command -v confluent | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -27794,11 +27966,17 @@ playground_bashly_reload_parse_requirements() { done # :command.dependencies_filter - if command -v bashly >/dev/null 2>&1; then - deps['bashly']="$(command -v bashly | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v bashly >/dev/null 2>&1; then printf "missing dependency: bashly\n" >&2 - printf "%s\n" "visit https://bashly.dannyb.co/installation/ to install" >&2 + printf "%s\n\n" "visit https://bashly.dannyb.co/installation/ to install" >&2 + missing_deps=1 + else + deps['bashly']="$(command -v bashly | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -28087,6 +28265,7 @@ playground_state_set_parse_requirements() { exit 1 fi + if [[ -z ${args['value']+x} ]]; then printf "missing required argument: VALUE\nusage: playground state set KEY VALUE\n" >&2 # :command.examples_on_error @@ -28455,6 +28634,7 @@ playground_config_set_parse_requirements() { exit 1 fi + if [[ -z ${args['value']+x} ]]; then printf "missing required argument: VALUE\nusage: playground config set KEY VALUE\n" >&2 # :command.examples_on_error @@ -28979,11 +29159,17 @@ playground_run_parse_requirements() { done # :command.dependencies_filter - if command -v fzf >/dev/null 2>&1; then - deps['fzf']="$(command -v fzf | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v fzf >/dev/null 2>&1; then printf "missing dependency: fzf\n" >&2 - printf "%s\n" "visit https://github.com/junegunn/fzf#installation to install" >&2 + printf "%s\n\n" "visit https://github.com/junegunn/fzf#installation to install" >&2 + missing_deps=1 + else + deps['fzf']="$(command -v fzf | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -29388,11 +29574,17 @@ playground_re_run_parse_requirements() { done # :command.dependencies_filter - if command -v fzf >/dev/null 2>&1; then - deps['fzf']="$(command -v fzf | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v fzf >/dev/null 2>&1; then printf "missing dependency: fzf\n" >&2 - printf "%s\n" "visit https://github.com/junegunn/fzf#installation to install" >&2 + printf "%s\n\n" "visit https://github.com/junegunn/fzf#installation to install" >&2 + missing_deps=1 + else + deps['fzf']="$(command -v fzf | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -29487,11 +29679,17 @@ playground_history_parse_requirements() { done # :command.dependencies_filter - if command -v fzf >/dev/null 2>&1; then - deps['fzf']="$(command -v fzf | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v fzf >/dev/null 2>&1; then printf "missing dependency: fzf\n" >&2 - printf "%s\n" "visit https://github.com/junegunn/fzf#installation to install" >&2 + printf "%s\n\n" "visit https://github.com/junegunn/fzf#installation to install" >&2 + missing_deps=1 + else + deps['fzf']="$(command -v fzf | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -29637,11 +29835,17 @@ playground_switch_ccloud_parse_requirements() { done # :command.dependencies_filter - if command -v confluent >/dev/null 2>&1; then - deps['confluent']="$(command -v confluent | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v confluent >/dev/null 2>&1; then printf "missing dependency: confluent\n" >&2 - printf "%s\n" "visit https://docs.confluent.io/confluent-cli/current/overview.html to install" >&2 + printf "%s\n\n" "visit https://docs.confluent.io/confluent-cli/current/overview.html to install" >&2 + missing_deps=1 + else + deps['confluent']="$(command -v confluent | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -29859,11 +30063,17 @@ playground_open_parse_requirements() { done # :command.dependencies_filter - if command -v fzf >/dev/null 2>&1; then - deps['fzf']="$(command -v fzf | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v fzf >/dev/null 2>&1; then printf "missing dependency: fzf\n" >&2 - printf "%s\n" "visit https://github.com/junegunn/fzf#installation to install" >&2 + printf "%s\n\n" "visit https://github.com/junegunn/fzf#installation to install" >&2 + missing_deps=1 + else + deps['fzf']="$(command -v fzf | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -30137,11 +30347,17 @@ playground_cleanup_cloud_resources_parse_requirements() { env_var_names+=("GCP_KEYFILE_CONTENT") # :command.dependencies_filter - if command -v confluent >/dev/null 2>&1; then - deps['confluent']="$(command -v confluent | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v confluent >/dev/null 2>&1; then printf "missing dependency: confluent\n" >&2 - printf "%s\n" "visit https://docs.confluent.io/confluent-cli/current/overview.html to install" >&2 + printf "%s\n\n" "visit https://docs.confluent.io/confluent-cli/current/overview.html to install" >&2 + missing_deps=1 + else + deps['confluent']="$(command -v confluent | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -30251,11 +30467,17 @@ playground_repro_parse_requirements() { env_var_names+=("OUTPUT_FOLDER") # :command.dependencies_filter - if command -v fzf >/dev/null 2>&1; then - deps['fzf']="$(command -v fzf | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v fzf >/dev/null 2>&1; then printf "missing dependency: fzf\n" >&2 - printf "%s\n" "visit https://github.com/junegunn/fzf#installation to install" >&2 + printf "%s\n\n" "visit https://github.com/junegunn/fzf#installation to install" >&2 + missing_deps=1 + else + deps['fzf']="$(command -v fzf | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -30342,11 +30564,17 @@ playground_repro_export_parse_requirements() { done # :command.dependencies_filter - if command -v git >/dev/null 2>&1; then - deps['git']="$(command -v git | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v git >/dev/null 2>&1; then printf "missing dependency: git\n" >&2 - printf "%s\n" "visit https://git-scm.com/downloads to install" >&2 + printf "%s\n\n" "visit https://git-scm.com/downloads to install" >&2 + missing_deps=1 + else + deps['git']="$(command -v git | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -32849,11 +33077,17 @@ playground_tools_install_vscode_extension_parse_requirements() { done # :command.dependencies_filter - if command -v code >/dev/null 2>&1; then - deps['code']="$(command -v code | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v code >/dev/null 2>&1; then printf "missing dependency: code\n" >&2 - printf "%s\n" "visit https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line to install" >&2 + printf "%s\n\n" "visit https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line to install" >&2 + missing_deps=1 + else + deps['code']="$(command -v code | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -34234,11 +34468,17 @@ playground_get_jmx_metrics_parse_requirements() { done # :command.dependencies_filter - if command -v java >/dev/null 2>&1; then - deps['java']="$(command -v java | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v java >/dev/null 2>&1; then printf "missing dependency: java\n" >&2 - printf "%s\n" "visit https://openjdk.org/install/ to install" >&2 + printf "%s\n\n" "visit https://openjdk.org/install/ to install" >&2 + missing_deps=1 + else + deps['java']="$(command -v java | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -37064,11 +37304,17 @@ playground_connector_plugin_search_jar_parse_requirements() { done # :command.dependencies_filter - if command -v javap >/dev/null 2>&1; then - deps['javap']="$(command -v javap | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v javap >/dev/null 2>&1; then printf "missing dependency: javap\n" >&2 - printf "%s\n" "visit https://openjdk.org/install/ to install" >&2 + printf "%s\n\n" "visit https://openjdk.org/install/ to install" >&2 + missing_deps=1 + else + deps['javap']="$(command -v javap | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -38629,11 +38875,17 @@ playground_connector_select_config_parse_requirements() { done # :command.dependencies_filter - if command -v fzf >/dev/null 2>&1; then - deps['fzf']="$(command -v fzf | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v fzf >/dev/null 2>&1; then printf "missing dependency: fzf\n" >&2 - printf "%s\n" "visit https://github.com/junegunn/fzf#installation to install" >&2 + printf "%s\n\n" "visit https://github.com/junegunn/fzf#installation to install" >&2 + missing_deps=1 + else + deps['fzf']="$(command -v fzf | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -40042,11 +40294,17 @@ playground_ec2_sync_repro_folder_parse_requirements() { done # :command.dependencies_filter - if command -v rsync >/dev/null 2>&1; then - deps['rsync']="$(command -v rsync | head -n1)" - else + missing_deps= + # :dependency.filter + if ! command -v rsync >/dev/null 2>&1; then printf "missing dependency: rsync\n" >&2 - printf "%s\n" "rsync needs to be installed" >&2 + printf "%s\n\n" "rsync needs to be installed" >&2 + missing_deps=1 + else + deps['rsync']="$(command -v rsync | head -n1)" + fi + + if [[ -n $missing_deps ]]; then exit 1 fi @@ -40267,20 +40525,22 @@ before_hook() { # :command.initialize initialize() { - version="1.0.0" - long_usage='' + declare -g version="1.0.0" set -e } # :command.run run() { - declare -A args=() - declare -A deps=() - declare -a other_args=() - declare -a env_var_names=() - declare -a input=() - declare -A unique_lookup=() + # :command.globals + declare -g long_usage='' + declare -g -A args=() + declare -g -a other_args=() + declare -g -A deps=() + declare -g -a env_var_names=() + declare -g -a input=() + declare -g -A unique_lookup=() + normalize_input "$@" parse_requirements "${input[@]}" before_hook @@ -40459,5 +40719,7 @@ run() { esac } -initialize -run "$@" +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + initialize + run "$@" +fi diff --git a/scripts/cli/playground.yaml b/scripts/cli/playground.yaml index 83ec77633a..8cd470630b 100644 --- a/scripts/cli/playground.yaml +++ b/scripts/cli/playground.yaml @@ -13,6 +13,7 @@ subcommands: usage: playground help [COMMAND] options: [] subcommands: + - name: status description: | 🗺️ Show a status @@ -78,6 +79,7 @@ subcommands: browser to use usage: playground config open-ccloud-connector-in-browser browser [BROWSER] options: [] + - name: run description: | 🕹️ Run any example ! @@ -382,24 +384,28 @@ subcommands: Force interactive mode subcommands: + - name: re-run description: | ⚡ Simply re-run last example you ran with usage: playground re-run options: [] subcommands: + - name: get-ci-result description: | 🤖 get CI result for current example usage: playground get-ci-result options: [] subcommands: + - name: history description: | 🏰 Get an history of the examples which were run with run command and run it again usage: playground history options: [] subcommands: + - name: switch-ccloud description: | 🌩️ Switch to ccloud environment. @@ -408,12 +414,14 @@ subcommands: usage: playground switch-ccloud options: [] subcommands: + - name: switch-back description: | 💺 Switch back from previous environment before switch-ccloud was called. usage: playground switch-back options: [] subcommands: + - name: update-version description: | ✨ Update current confluent platform or connector(s) with new version(s) @@ -466,6 +474,7 @@ subcommands: use playground config folder_zip_or_jar ... (default is home folder and current folder is always included) to configure where to search the files subcommands: + - name: open description: | 👐 When --file is not provided, simply open last example you ran with @@ -491,18 +500,21 @@ subcommands: 😴 Wait subcommands: + - name: stop description: | 🛑 Stop currently running example usage: playground stop options: [] subcommands: + - name: remove-all-docker-images description: | 🧨 Remove all docker images (including docker volumes) usage: playground remove-all-docker-images options: [] subcommands: + - name: cleanup-cloud-details description: | 🧼 playground is actively caching ccloud details (https://kafka-docker-playground.io/#/how-to-use?id=%f0%9f%8c%a4%ef%b8%8f-confluent-cloud-examples) @@ -510,6 +522,7 @@ subcommands: usage: playground cleanup-cloud-details options: [] subcommands: + - name: open-docs description: | 🧑‍🎓 Open Confluent documentation of currently running example @@ -522,6 +535,7 @@ subcommands: 🌐 Only show url subcommands: + - name: cleanup-cloud-resources description: | 🧹 Cleanup cloud resources that were created by running examples from the playground @@ -683,6 +697,7 @@ subcommands: Conflicts with: --producer + - name: get-docker-compose description: | 🐋 Get docker-compose @@ -1542,6 +1557,7 @@ subcommands: Allowed values: INFO, WARN, DEBUG, TRACE + - name: get-jmx-metrics description: | 🔢 Get JMX metrics from a container diff --git a/scripts/cli/src/commands/connector/show-lag.sh b/scripts/cli/src/commands/connector/show-lag.sh index 3dd41a140b..7d150cc5ec 100644 --- a/scripts/cli/src/commands/connector/show-lag.sh +++ b/scripts/cli/src/commands/connector/show-lag.sh @@ -133,7 +133,7 @@ function log_up() { function log_same() { ORANGE='\033[0;33m' NC='\033[0m' # No Color - echo -e "$ORANGE`date +"%H:%M:%S"` 🔸$@$NC" + echo -e "$ORANGE$(date +"%H:%M:%S") 🔸$@$NC" } tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) diff --git a/scripts/cli/templates/shell-script-command-completion/render.rb b/scripts/cli/templates/shell-script-command-completion/render.rb index 32c6eae6f3..0b3b58527f 100644 --- a/scripts/cli/templates/shell-script-command-completion/render.rb +++ b/scripts/cli/templates/shell-script-command-completion/render.rb @@ -45,6 +45,7 @@ else unless processed_subcommands.include?(subcommand.full_name) File.open("#{target}/playground.yaml", "a") do |file| + file.write("\n") file.write(gtxsub.parse(subcommand)) end processed_subcommands << subcommand.full_name From d05118ac4103695264f4ffa76cd32d39ce1c4d81 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 7 Mar 2025 16:42:20 +0100 Subject: [PATCH 285/659] wip --- reproduction-models | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reproduction-models b/reproduction-models index e57e2da781..519aee89c5 160000 --- a/reproduction-models +++ b/reproduction-models @@ -1 +1 @@ -Subproject commit e57e2da781d16cbc74aa604083b653aafed04a47 +Subproject commit 519aee89c56daa9f26ce7c990b9b796a4ffde2e1 From 4c65a5c20f9276c485ff84140730edebce60503d Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 11 Mar 2025 09:22:27 +0100 Subject: [PATCH 286/659] updated --- scripts/cli/confluent-kafka-region-list.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/cli/confluent-kafka-region-list.txt b/scripts/cli/confluent-kafka-region-list.txt index 4cdd63ac7e..281f100a85 100644 --- a/scripts/cli/confluent-kafka-region-list.txt +++ b/scripts/cli/confluent-kafka-region-list.txt @@ -25,6 +25,7 @@ Ireland(eu-west-1)/eu-west-1 Ireland(northeurope)/northeurope Jakarta(ap-southeast-3)/ap-southeast-3 Jakarta(asia-southeast2)/asia-southeast2 +JioIndiaWest(jioindiawest)/jioindiawest Johannesburg/southafricanorth (southafricanorth)/ LasVegas(us-west4)/us-west4 From 271f66e77aec29f2e6a6942d8731ab030152502a Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 11 Mar 2025 11:42:55 +0100 Subject: [PATCH 287/659] Update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dbde225375..8e1c95a5d5 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,12 @@ Check out [kafka-docker-playground.io](https://kafka-docker-playground.io/) to l [![asciicast](https://asciinema.org/a/643687.svg)](https://asciinema.org/a/643687) +## 🎙️ Podcast + + + +Made with love ♥️ by AI + ## 🏁 Getting Started Check out the **[How to Use](https://kafka-docker-playground.io/#/how-to-use.md)** section, then select an example in the **[Content](https://kafka-docker-playground.io/#/content)** section and run it ! @@ -45,4 +51,4 @@ Love it? Give it a ⭐️ by clicking below: ## ⭐️ Star History -[![Star History Chart](https://api.star-history.com/svg?repos=vdesabou/kafka-docker-playground&type=Date)](https://star-history.com/#vdesabou/kafka-docker-playground&Date) \ No newline at end of file +[![Star History Chart](https://api.star-history.com/svg?repos=vdesabou/kafka-docker-playground&type=Date)](https://star-history.com/#vdesabou/kafka-docker-playground&Date) From 331a9ac554adb401f4a1cf196f7dba756256a665 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 11 Mar 2025 12:22:12 +0100 Subject: [PATCH 288/659] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e1c95a5d5..137ebf9fc0 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Check out [kafka-docker-playground.io](https://kafka-docker-playground.io/) to l ## 🎙️ Podcast - + Made with love ♥️ by AI From 81b27c956a1182df0e215dc7ff74cd3a74ae3fe8 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 11 Mar 2025 12:24:30 +0100 Subject: [PATCH 289/659] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 137ebf9fc0..6816f3362d 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Check out [kafka-docker-playground.io](https://kafka-docker-playground.io/) to l ## 🎙️ Podcast - +[![podcast](./images/podcast.jpg)](https://youtu.be/zV56G1Gz1kI "Podcast") Made with love ♥️ by AI From 54f9a3a3bb5100b30547f286cd17934ae9824826 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 11 Mar 2025 12:25:48 +0100 Subject: [PATCH 290/659] Add files via upload --- images/podcast.jpg | Bin 0 -> 587902 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/podcast.jpg diff --git a/images/podcast.jpg b/images/podcast.jpg new file mode 100644 index 0000000000000000000000000000000000000000..44945e2aaa73d249c9df2e8be111afee9e01a42f GIT binary patch literal 587902 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

4Adz_nDN=&Yh-3&OROObXkZn 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

ee*IK>IG2&4Dzr7In_ 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�&L_mh0MT}lnlY68NVI(wP0$1>!BS09l!JB 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

wJz-ovZ`#D-j+gJYWX}+n)?;!?|5q)u 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

tnAVq{wJ-fiqHHMv9OwN7pcV$~RGA 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�-NpQw|^c1UmsA(}%OaE;G}-|5oKQ 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 E0A)5Ii2wiq literal 0 HcmV?d00001 From 0acbc0d2cf8b09bd263d7de70c2733c790c0f77f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 12 Mar 2025 09:53:41 +0100 Subject: [PATCH 291/659] minor --- .../gcp-pubsub-source-nginx-proxy.sh | 2 +- scripts/cli/playground | 12 ++++++------ scripts/cli/src/commands/container/get-properties.sh | 2 +- scripts/cli/src/lib/utils_function.sh | 10 +++++----- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh b/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh index 000e83ca8b..97c12c2c5b 100755 --- a/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh +++ b/connect/connect-gcp-pubsub-source/gcp-pubsub-source-nginx-proxy.sh @@ -4,7 +4,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" source ${DIR}/../../scripts/utils.sh -if [ `uname -m` = "arm64" ] +if [ "$(uname -m)" = "arm64" ] then logwarn "This example does not work on arm64" exit 111 diff --git a/scripts/cli/playground b/scripts/cli/playground index 37745c02c9..8509c8ac1e 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8598,7 +8598,7 @@ function maybe_create_image() if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" then export CONNECT_USER="appuser" - if [ `uname -m` = "arm64" ] + if [ "$(uname -m)" = "arm64" ] then CONNECT_3RDPARTY_INSTALL="if [ ! -f /tmp/done ]; then yum -y install --disablerepo='Confluent*' bind-utils openssl unzip findutils net-tools nc jq which iptables libmnl krb5-workstation krb5-libs vim && yum clean all && rm -rf /var/cache/yum && rpm -i --nosignature https://yum.oracle.com/repo/OracleLinux/OL8/appstream/aarch64/getPackage/tcpdump-4.9.3-3.el8.aarch64.rpm && touch /tmp/done; fi" else @@ -9747,7 +9747,7 @@ function remove_cdb_oracle_image() { SETUP_FILE=${SETUP_FOLDER}/01_user-setup.sh SETUP_FILE_CKSUM=$(cksum $SETUP_FILE | awk '{ print $1 }') - if [ `uname -m` = "arm64" ] + if [ "$(uname -m)" = "arm64" ] then export ORACLE_IMAGE="db-prebuilt-arm64-$SETUP_FILE_CKSUM:$ORACLE_VERSION" else @@ -9775,7 +9775,7 @@ function create_or_get_oracle_image() { then ORACLE_VERSION="21.3.0-ee" else - if [ `uname -m` = "arm64" ] + if [ "$(uname -m)" = "arm64" ] then ZIP_FILE="LINUX.ARM64_1919000_db_home.zip" else @@ -9790,7 +9790,7 @@ function create_or_get_oracle_image() { SETUP_FILE=${SETUP_FOLDER}/01_user-setup.sh SETUP_FILE_CKSUM=$(cksum $SETUP_FILE | awk '{ print $1 }') - if [ `uname -m` = "arm64" ] + if [ "$(uname -m)" = "arm64" ] then export ORACLE_IMAGE="db-prebuilt-arm64-$SETUP_FILE_CKSUM:$ORACLE_VERSION" else @@ -12236,7 +12236,7 @@ function check_arm64_support() { DIR="$1" DOCKER_COMPOSE_FILE="$2" set +e - if [ `uname -m` = "arm64" ] + if [ "$(uname -m)" = "arm64" ] then test=$(echo "$DOCKER_COMPOSE_FILE" | awk -F"/" '{ print $(NF-2)"/"$(NF-1) }') base_folder=$(echo $test | cut -d "/" -f 1) @@ -19956,7 +19956,7 @@ then logerror 'ERROR: Could not determine properties file!' exit 1 fi -cat \$propertie_file | grep -v None | grep . | sort +cat \$propertie_file | grep -v None | grep . EOF } diff --git a/scripts/cli/src/commands/container/get-properties.sh b/scripts/cli/src/commands/container/get-properties.sh index 3feb47e1f2..df293c7375 100644 --- a/scripts/cli/src/commands/container/get-properties.sh +++ b/scripts/cli/src/commands/container/get-properties.sh @@ -10,5 +10,5 @@ then logerror 'ERROR: Could not determine properties file!' exit 1 fi -cat \$propertie_file | grep -v None | grep . | sort +cat \$propertie_file | grep -v None | grep . EOF \ No newline at end of file diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 2670dcc893..c3d5d09c6f 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -262,7 +262,7 @@ function maybe_create_image() if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" then export CONNECT_USER="appuser" - if [ `uname -m` = "arm64" ] + if [ "$(uname -m)" = "arm64" ] then CONNECT_3RDPARTY_INSTALL="if [ ! -f /tmp/done ]; then yum -y install --disablerepo='Confluent*' bind-utils openssl unzip findutils net-tools nc jq which iptables libmnl krb5-workstation krb5-libs vim && yum clean all && rm -rf /var/cache/yum && rpm -i --nosignature https://yum.oracle.com/repo/OracleLinux/OL8/appstream/aarch64/getPackage/tcpdump-4.9.3-3.el8.aarch64.rpm && touch /tmp/done; fi" else @@ -1414,7 +1414,7 @@ function remove_cdb_oracle_image() { SETUP_FILE=${SETUP_FOLDER}/01_user-setup.sh SETUP_FILE_CKSUM=$(cksum $SETUP_FILE | awk '{ print $1 }') - if [ `uname -m` = "arm64" ] + if [ "$(uname -m)" = "arm64" ] then export ORACLE_IMAGE="db-prebuilt-arm64-$SETUP_FILE_CKSUM:$ORACLE_VERSION" else @@ -1442,7 +1442,7 @@ function create_or_get_oracle_image() { then ORACLE_VERSION="21.3.0-ee" else - if [ `uname -m` = "arm64" ] + if [ "$(uname -m)" = "arm64" ] then ZIP_FILE="LINUX.ARM64_1919000_db_home.zip" else @@ -1457,7 +1457,7 @@ function create_or_get_oracle_image() { SETUP_FILE=${SETUP_FOLDER}/01_user-setup.sh SETUP_FILE_CKSUM=$(cksum $SETUP_FILE | awk '{ print $1 }') - if [ `uname -m` = "arm64" ] + if [ "$(uname -m)" = "arm64" ] then export ORACLE_IMAGE="db-prebuilt-arm64-$SETUP_FILE_CKSUM:$ORACLE_VERSION" else @@ -3969,7 +3969,7 @@ function check_arm64_support() { DIR="$1" DOCKER_COMPOSE_FILE="$2" set +e - if [ `uname -m` = "arm64" ] + if [ "$(uname -m)" = "arm64" ] then test=$(echo "$DOCKER_COMPOSE_FILE" | awk -F"/" '{ print $(NF-2)"/"$(NF-1) }') base_folder=$(echo $test | cut -d "/" -f 1) From 4b861044f240c712e867b7c91ce18d707bc1850d Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 12 Mar 2025 09:59:55 +0100 Subject: [PATCH 292/659] call to handle_aws_credentials in create_or_get_oracle_image --- scripts/cli/playground | 3 +++ scripts/cli/src/lib/utils_function.sh | 3 +++ 2 files changed, 6 insertions(+) diff --git a/scripts/cli/playground b/scripts/cli/playground index 8509c8ac1e..fd0938593d 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -9803,6 +9803,7 @@ function create_or_get_oracle_image() { set +e log "attempting to get the Oracle prebuilt docker image from Confluent S3 bucket (only works for Confluent employees)..." log "command is " + handle_aws_credentials aws s3 ls s3://kafka-docker-playground/3rdparty/$ORACLE_IMAGE.tar if [ $? -eq 0 ] then @@ -9849,6 +9850,7 @@ function create_or_get_oracle_image() { if test -z "$(docker images -q $BASE_ORACLE_IMAGE)" then set +e + handle_aws_credentials aws s3 ls s3://kafka-docker-playground/3rdparty/oracle_database_$ORACLE_VERSION.tar > /dev/null 2>&1 if [ $? -eq 0 ] then @@ -9886,6 +9888,7 @@ function create_or_get_oracle_image() { if [ ! -f ${ZIP_FILE} ] then set +e + handle_aws_credentials aws s3 ls s3://kafka-docker-playground/3rdparty/${ZIP_FILE} > /dev/null 2>&1 if [ $? -eq 0 ] then diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index c3d5d09c6f..b9349861c7 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -1470,6 +1470,7 @@ function create_or_get_oracle_image() { set +e log "attempting to get the Oracle prebuilt docker image from Confluent S3 bucket (only works for Confluent employees)..." log "command is " + handle_aws_credentials aws s3 ls s3://kafka-docker-playground/3rdparty/$ORACLE_IMAGE.tar if [ $? -eq 0 ] then @@ -1516,6 +1517,7 @@ function create_or_get_oracle_image() { if test -z "$(docker images -q $BASE_ORACLE_IMAGE)" then set +e + handle_aws_credentials aws s3 ls s3://kafka-docker-playground/3rdparty/oracle_database_$ORACLE_VERSION.tar > /dev/null 2>&1 if [ $? -eq 0 ] then @@ -1553,6 +1555,7 @@ function create_or_get_oracle_image() { if [ ! -f ${ZIP_FILE} ] then set +e + handle_aws_credentials aws s3 ls s3://kafka-docker-playground/3rdparty/${ZIP_FILE} > /dev/null 2>&1 if [ $? -eq 0 ] then From 606dcb6e17916615e14e7005664597e4083bc989 Mon Sep 17 00:00:00 2001 From: ImgBotApp Date: Wed, 12 Mar 2025 09:20:38 +0000 Subject: [PATCH 293/659] [ImgBot] Optimize images *Total -- 1,103.92kb -> 776.88kb (29.63%) /connect/connect-datadog-logs-sink/dd_logs.png -- 285.81kb -> 152.88kb (46.51%) /images/icons/azure_loganalytics.png -- 6.96kb -> 4.39kb (36.97%) /connect/connect-datadog-logs-sink/app_key_dd.png -- 230.02kb -> 145.27kb (36.85%) /connect/connect-datadog-logs-sink/api_key_dd.png -- 245.99kb -> 158.44kb (35.59%) /ccloud/fm-gcp-cloud-functions-gen2-sink/Screenshot1.png -- 60.68kb -> 47.53kb (21.67%) /ccloud/fm-gcp-cloud-functions-gen2-sink/Screenshot2.png -- 34.77kb -> 28.79kb (17.2%) /images/icons/opensearch.png -- 3.04kb -> 2.95kb (2.99%) /connect/connect-servicenow-sink/Screenshot1.jpg -- 118.32kb -> 118.32kb (0%) /ccloud/fm-servicenow-sink/Screenshot1.jpg -- 118.32kb -> 118.32kb (0%) Signed-off-by: ImgBotApp --- .../Screenshot1.png | Bin 62139 -> 48672 bytes .../Screenshot2.png | Bin 35600 -> 29476 bytes ccloud/fm-servicenow-sink/Screenshot1.jpg | Bin 121161 -> 121157 bytes .../connect-datadog-logs-sink/api_key_dd.png | Bin 251895 -> 162239 bytes .../connect-datadog-logs-sink/app_key_dd.png | Bin 235538 -> 148753 bytes connect/connect-datadog-logs-sink/dd_logs.png | Bin 292674 -> 156553 bytes .../connect-servicenow-sink/Screenshot1.jpg | Bin 121161 -> 121157 bytes images/icons/azure_loganalytics.png | Bin 7130 -> 4494 bytes images/icons/opensearch.png | Bin 3113 -> 3020 bytes 9 files changed, 0 insertions(+), 0 deletions(-) diff --git a/ccloud/fm-gcp-cloud-functions-gen2-sink/Screenshot1.png b/ccloud/fm-gcp-cloud-functions-gen2-sink/Screenshot1.png index ffa6a199628caf1825d2fa27523f764b8b1005d7..ada166a87ef3bc5c84270d0e20bbef5696f1c530 100644 GIT binary patch literal 48672 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 G@BbfvA&CP3 literal 62139 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 Ra)!E2HPv+w6sR7*^go)2H;w=R literal 35600 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ưfi@4>z2<3O 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 literal 251895 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 WHuL;|DYypTT`@4ZSbo9f?*9UU?WNNI diff --git a/connect/connect-datadog-logs-sink/app_key_dd.png b/connect/connect-datadog-logs-sink/app_key_dd.png index d5bbb54249cc8fd97261a0040dfb2535786b7103..a84e53e40c2d5eabd68f019a79ce78e18458b5b2 100644 GIT binary patch literal 148753 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

f`u~-C%&dqR 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 literal 235538 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%0Ag*z^vp~P&>S|y=}>7FpbR){ zBhQ;pdcL#U6FrVSZ$Pl(_;>2+cOTUsbDxz2-~X6rQC*El-*msUsk~k2A#0Iy=D$Tm z|M5FsUHLov_>nxhX zTD0@_+i#Y0&15KXL<|m|MO5n=5uBNNHiza*H`X|Pga(XmbXuS^w&W;tr61Rjm=iUT zEC?T?&CwFLuuICZBom(&y3ER&; z{hZDKW1BmI2GevNrOr6XDdsl}Q4MT%u*Us)$il}Ig`BnncaIeb$V-U-;?CzumA~~0 zOX%+qpJVVAy4s_YH*xq@M}O-v?_pHdHXzJ+_uJzqivE#>v+a>AR0_lXQS|g(A-(WH zHW%v#hu@fk6HRUQ0a*vj`bKOnc6V5q+Nxz8bL`K6G+CfwiiELEEN+_2fP6=*R_v~TXm|q( zjk7Nc?n1J>H`}-00d!@6!`3GBnnB3e@&PZ{n*e#6`3`5pU$kV0X=I)Sz5Iwg=4XAp z$mtM5%CPKMQva)W2nt3-LPGNaY*ieREnz=;?-bn8+@E%fjHWRHfAG5hIt8vH1eKxZ*~_}@PCmo7toh$bnC&e|L3?OKWo`fqpjx4+X)-v=D-t`**n zId}e_UiekC{5~U3d-X85&A#R6Kfd(WKz|a@JN8<{`QZKr_$ObVXbXtOnuvpgf7TH4 zA0K+@%6HLNrKOd&#od-`=G%((0~S3ZEU*rkMDQ-aM3qpbJ^^I! zRe6UJ}qkK?S;5 zAXQ2R3HX2f?cArktP#UUeWDnHe~vu=wOZd_$*0g14I}q~On-F-~B52W4megI@-ucrO38I9LBO^4pIM z7w>h@00-psErikXC*M8rDLQTB*SUIbo2PxToGQ=X^d);@>|2~XsP=tRkIPkl?IZv# z)Jc4nMgc#X{C)#2eMu9{?>y(rV?|<6T+0fTjifbz5SF4J`FpC~o(c$+m9+RpyTYr# z-)w8$m&tuU(u+Nw;}1*LdNuFKfZXm*A&r>Srqx@~!AwFXLG2emQ{xI?Vy-gnJ}i>$k~W5w+*uY;I78KS6?lrDzG$r-L5ne^|%*V&LMdCr{D42BcxmUrN5IqF!cvaD8Eb3 zZ&YyQ>AdsW3l3pht=tE1o#xNZ)&FrY{`}tbh5Z)OBxb<= z^l$QXkiXl$-kW~1o>((rFTWfgSo`FiY8dTyixBPdCOGv8v@h+9^#fqcUb`AFwMAhQ z{`Ygk{&ZM82zfvkyEjuOaR1!Q|8Z^>1@j*FeMu}$?30wfTzb5srbybQJ=17cBtqG0 zRdVoId3m`;mkVM^bwr35CmL!Eo1o^!1Bp|-XE$@G6!+ZErpbN3OF!Pr-y;{@Pd48k z{IMK~XAflCmfJOrzo?Re*+Oz6<;a>zkzj%(1eH5cHs-6Fnu~fnEUId4ba9}-3V+6Z z&c8+2`-__LSXI;9`D@D~Ei=(UkIiZgSpB#J*SKjegi z6ZRAJjx@9{%tnv!BxLSa)M1Wj})MPYU~B6)j2sq z0i(lgcs;Jb2v@}*I}6lFwC2WYNX3- zQ86D5{P^SFvucBlNtdPXrFHuE1 z%^3hfrjvzdE1gGOjnB?h0*zKUIB)c7Ga|veZVCHg@&eEC;R-YQLK6t(<9efQ`SbSO ziw<+XoN6b^YlPk8$n~ll-J6;n8BOomxnSgyhXy;XWoJ77o-OcWr^xFc24ako`GVv1 z`G4*iNk72RAC}PvT1L1YEMpUlP(F*2rM4q>5;`$3G2W1`Na$Oyc}-0;VJoCYhL5ZB z>>|+3z4<1S&ByEg(9;G4hPuq`PV7EXHTD!3n3*)?w({}PvuDqMK3i^_xP62xPD09W z+|~+P5xKcEt`jS2zvOI`9;q{t8#y{^WYv3h-2IB(OSduK3&tg@gI3$6_I(dxuZSKS z9zZ_<^r@a&EZPqNI&YSJ7_B-^Ik20G!Rs~K{IW)nVuD}iv^ zQ4d(1p3n+A#ROPIjUN6Cua|AJDSLkZig5nV;r#1It>o`%%u%2I^rqI1@5j0KsUI+# zo~E)2DiBLMY7)w}6|Zw+=UjVw%9)8=W1$Q*;bVhnkc8LZhsSTa@}>fXs0zUx9UodC z$Tlv*#1xbLdEcoHbA$$yDcUV!6sRa1Xxghm`|u1<=QCfBD%r%&?iL!_i`3Pf>4{idiLtes9qDJvu$+PDG9VqgsOM~kMcAaL@1mtWYPNBulY^Z)|MQ{-P zOVQ{ouqAa`x8{cV7H%MXR|G6hl8f6)mD!j^jA5cZYu~=c65*F}E7yuXOW4lW1iJn_ zu<{ExlBZ``;CtSZ9De@yksp~sV&<{)Qt>C(!hopcw47+5JfONSrnWyIL3W;LNf++JB&;j_OeEv@v$B#~*DrRW+b zi&~8Rz%m-j4__NUV!jp2_vI}fr|1?F5Uiot?s%l|?fa(|N(@r;|9E z!08e+6>~m`ki~3R+-jYdhFR=KuQ)3pygjxVy{)kC;`hBxC3u&saJ(-Anu$@1v)`A& z)ZeB~p>-zWx{&q**Jh^xY>zKy+=(P>KMz5m0}Q2s(lrCvZRzYMOv?H7u(Bk3rlzdKaej%xh7B4vaEgXVzXg4eFhnJ3d$7f9|z&Rw)K*VeLF31zUQ^ z66if(HEK6fV23u|bT=)u_qY6t2UBM1#_%4rBP)Hj2O)cM#d0?BFc|Ukv z^2}$ttV$0R1JtL(!$zM*c&FkgN42geI|grU51}0p=;2EJFtpL=%hFuvyW{oMV^O6Xz)ex`H0!! zqJsHvW)o)?cE?k$na62B5=L|ELdk9okvuOE6_m-Mm%J%%h-#awZh-Qdc{sEs=>6OE z6+t(5EQ8@wfPaA|`{3KyQq2NqS3DA5!+3n=1E2`sjr&#uCB-8G*YY#=h-qx2Tkd$4 z*qQqlA=f93jk~AFaXu#|;M#e{e8JlbI$E-u@*WinnIj&A`4#7nw8lyZ&ywTwzL^*| z=-;f^zp$@0I?FyF05UoG7yhaA_3Nkl-^{|l)S(oKPq;;`zS&E$KBaR6?F{9mjqHA| zzg9(`#yHTo>3@U_J7QFdt-^I`f~ob$knyI?b2JcS$jv9|qN*yJL!2wELtLGXXrHx7 zZJ0jG_R<(np*couq_R!}p}_-ndFLXXz55CV{s4G3ggsVnOS|Q~^st5LO}=oX223G- zn3};t;q@e>zLwEOJ{?HYQJ4N+iI=YO1;e}>Tl>uQk#;p3J%Jq?VKaPB3z=?imE^MU zyX7{Jyl5HDKdi7DFVNxe`KB-FHT^r``d_#BH}>!7H2^@eFee6`7(&slRxU`uTCdD; zcBl?>R8cw3JvW#He~sRJPW+KkXz3s9?(PnQ8y78FK%pgo9_IUbvjs`iV@UFbrIbLq zoq?iAul8gKqMB32rP=s>V4!n!75y06Eff&5@RTTTQ;!vOi!Ll|5aGCC`#Z3s3?6M7 zBRA6E8pcOrZ{Sp6m3$i7%PtZT4{!Mg12qwiaUX{ywRmB5jxy4T(r+^nA@qFjf>|Y# z2Jh#hXX)I(<|Es;I!(*;0ze#=!7Z*nH;W?`#Lf>REpA1&KR&XFOY9RxyDr!s%#|YV zjWNhv$|Y}MfIhQL0(|qxH)a%FeLOI=@&k#oQ#N5)jl#1CxJelKw7lLR8al*nwPCuwpELF9D^ACH1ibyesWI zqs^l|RHAOv{UQZ=rm9zRPMF6s6F2r%y z3?IcjbKGU|g9=XTAMs;1e$Bhk&9_GZEv>_};N0q^Q=URAB+8)$`}s#}3&<8sE;SS# z@_K`Lu;RL|Ty^Pn{_dI4Vd0I0TI_M5xDQ>6vK&x()onk+jl2xd!c9t+uNrteSy;z1soAo0qk5d7jcIphx;xJb-!s`E zf!nnls>umKa)hPFZ)6isBareN<=pP1MkcYvHB+%W3YB)hSGgee860_{$SF&&HsWS5<;i?`n3fGk7?pnF_NK^^GQHKm3upa!HL4>B?ZfIO~C z|AJrBQ1P<{_j$U@h`|%Ik$2!X&0>#P&pT;oXyhx*P0zLx-^azj)4)HiM>BQg)5G5x zj4y!6NAv-)-+6$D%bm^XDiG*DXkW*x>QQ4F$RN|bs7sY8p>~Xn0hPdP9v#W7^N$d zi>V#z49YCm7%$W(yv$2q85ORXcaK-P#%95iV2RZQdY?l~75HY~^AeI(-Ff*cmh#m=(Y<3`X( zL&dEIE5ygvl=_}|QLzCKvts=RNuygMhSLC@RHSKvvkmGsCs_Eu{lH&YATTJoJsC>Q zDq#jMzmM29_K&M6$1xNe&nAc7Xk#)?yqeR-Uw8R(tQU_kiVz*a?oZ_Kw9`oa9 zwLV@de9ED6=&*t*K!cT>4Z@>6Io4Jm^O{wysFC%N8tm?0yLr?b1*sYa`iuETR>H5m z_eO5^k;+IErKgRVeUvvJx2Ct3r}dGGk<`=31Jcn>Q}Fv5y5&`HY!2r4FsS1D6sy8^6(cKKpMyQp=$N{v1p+!CVEneLmQ0rSuBV9 z{m7Y>!lw0oykFbQ55PF!)Vp_7-Q2oQlVi6=QXF!FPnLVh>gw29Cj)2KTH368wQ8!= zzPQc48LuZBXyX`@X~7dP-e<#ki#i7~ zQ=+$H4T>!<8i2M?xiz8tz!Upy5`Cw0bc69uw@!2$IYj2sZG;rLT%4@0f>ag4Y}byJ zww>ZRigs^SIUV1*yaO^q6X?&#l;kGobLwb})}e*F{|;9r`fvHt&J0 zcC>~^dxTl_*5SPU#OFBCrLhFPvT2{)JNQTKghR>_ps zn+9$hbgN5uUV2= z@c6pVYTB=&IiKGVr{*;pQ+Kz(r^xzRBLJDCaqrT5s5KZ!Yg0I7uI`U)gz;#E;(XR^ zAaBQH*FL}G@QlSfr-=#`{2IU-Ox!Nnl69l>uuA5E85giffg9Y7|v#2tqv%HUjS%00JV{EYnO+U8BT$WT;WM{Tn5z$ ze}ceGC~nBGj~bepcHbgG%tnIY=DT&Cs}cLE{L*8Y8mhUF-o@VJV?1eDV(e|}A>01e zZBY(%X5@qrkioC5-+AghL%XxtEa+t=u|?`Uq~8-;Fww8F92@z~j^5m#Lm?#cOyKb0!g-;mcNsXZ zU<_7Q-Q*|A))AMV|6YgL4iy(zRmsy-v9D~SYdyc-d2^2OJzKA{T<*>HEm^%N=kTVZ z0&x;}Jq8zUn<)My$YDv7qUc=$1YOBo0hE#x6Zt5T){44+o{fD>eL_v-~PDK2g*A-u!8trfm0+yUXCMj~f0u-D(D` z$E}ZeFO~$I6aHBH8r2$g!+5|D+svbF;%oJRX)}W?T87WykwLy{GR7%J85?W#O|x z{p~~j!QGA74@s}_M48qK&`5R`*3jFY{%&$`cGJB;MfKh*gNk6bMkAvJXM^uP>IJLj65 z^rJZzC8$68ba}McGep*?(rm@3Jbpobj4hWJGOTa+kcMHpBYZ@^ly5~2y}cAlH`5lQ z?osX5eH^Ngfa7Tlq?N$M$X4f?ZJrB_t59lB>>}hFHn44+#otybg!G~RgNj=jfnXC<8mvsMHxkTi<+nK;PR4R9O zBZ@ve8QmF2-uyU3mln>y`|ahEDvbX=%z7c4UOPu`xOKB~V9rWVzr-LZ=~6c5@za~- ziH0(n^&lcMsjo_GpRR$Q#1wrVznBc#{zQ zW26Y7)ObY9rgYpZQrFZ=V>3!m^7&fcLQ-8&u}$B-EHq~M5OMQ#)h=IbvE|W zV-+{lMamUjWZylSbHyqH5!0Vdf4FjLmv;p%aEQ zdFo``D1YJ;s-(b5>=L_5{|VSZaO1l^emC!rd(sl(BXcXhkMESO>Ya=x7k(9c`C z{VoFOEe3wdvR4gZB{>ffcyMV1DRc@%!K#gUs0Plg`chnl<4P+FV-ClH@DGgJkl|@k zZ|r;Wsv$KI%%J%GjQ()pF(T0R1&7!_Q!+XOL3X3UxIEpu*=T-#+kwtmW4!` zMjLyc&>P|j*{M7Y>K(PPL-`m>DkJ3F-Z>)JnJjzx1KNBHn8iQS zEo?cDI`LYAFCnUpAuzfbM$Zxh>9y(w^g5!VGzV78mxs`r<7de^LncM{9%XnpG@9ve zdHyE;_mRtwcfX!0yM*)ryAmTVHpfeb%M6u=2R116#SRy1zx`(JpQf}-*kg<-{d%O( zq{#7Nd0T8|;m0i+Uy7GIHzX}+qX*>>d+nQd(6nf(CgM4rTGf*<1JNDluOhND`AQt3 zei@uTQr&8j#MO$eo+?aX!CvV^s%b6{_a#3om2eNWRmwtPT6kQAV#~`%`JvHmUl5VP zr2(qXQ(&4CxR4Iayr(~^_~A@hVh6mYsky~}ZsuzgK27Nw9|_rG71jMstih~Js5{Bq zrIo;5Q(o}0;)^3leP03asHER;aZc!vb9C!a;kw8bTw~Tqo^gro7>jm{t~H-!(-IG$X^2t(jno@LbZ6 z96bx~^OnxG0Y5Q%yXVh8o(Dg>eP%BYfFwB=Ts)`iNbw#9xu5lFo=bYq2Hm-Prx~Lf z-8TP>^Cq?u=9%UHiqyQ6(4YGj{|j`QqwIcsPML&Duj$^>Dwy9x+~TkvxboH0rb6sB zk{u|K;Lv6d5ee&QwirM-w{|L3TM6z_;t5nA^U36mnI#8xt;Y2!9nya=(&w7?h0^IxxN(75%T=k=;xnLTX{V(WfFP|0Oi~mw1X2x2sDX8_ zyl<78SXr1VUYwydO~6q0s3>k)MAH>-sY=g>_tm>R=CKt5pP-W6hP#7GE0i zmAAKL^pzrf0iq0iT4`z@cDC{tf+|5KKR)59xjx-UF+T)};rs_soVe;j827;nXwtP7vj#cz%zlyMnyHJ7-PIBU zNVXDUi|M^fs9tP`^H$d2k{i{FJ$fd`F|zD8Y`u=?(akK$mt(rR@1P;LC*m96{Z;!+ zL&wt21zMzN0;85AC)yF)+}83IR}Z@m&*2<0V&uf;A-V8x*R*OnJA~6sg<28>mXCb4 z-rl<9?b!k^mDsNQozVyzgfo^ZDHRUEPlYj7l5XxZ;{R3r_^+=nJU#3Z)ygNlR;b)S z6rMs!&IYqSR_~D8&K@`vOOfFfwy)lRqurDfM$2VZY}q0H%2r?)ALUTh$x?zF5ut8mM<~eak#|Q!isT< zQOpB#BB6>zXd{B+fS$6||Bth;fQo8s-(kLKZ(mm2Sgs3P2 zgLDs#v~-t9HvX)750%4O zmKyG<g)R%NrRYKIy~yhvu4?M-H?zTFKM zQlY1yqM}X;LM;kSJ1S>CDPK?Yl-E4MO1;U)bL;SL^A41(^p2fRnkLw|28Vs_aga_r zUHAc7Ui!G8%4)jzNCO*Q?lN&u6`V3*kfM4Bu7|Xruoo`|5z~@;Je|L}0KaOpfD}l0 zv~&5g_;S#qLI--Ji**7izZS+}abZyR-WAGFPVF@Jdx_Ssmp?Zqvg>_Lsb(Gn`osOg zVUgk2bg;L)7D(NuyrpK_VV`_tB4VBXlfqu~}P<(~XShb@}L`N1{ zrYwc%GcDF$?m5=6=7GC zJOZUXM=U#E@$AI1ax)N726H~o_d_35NLOr*d1>ou4Sw~=bZi|8=K)!gJ~X(tqDT5m z;Mfdp|NTKnD~vj|Wbym=Rr!!r?hJl(x#nZ{s=D1dr=bF;r-Ob| z)=@d=Gn?myE#os_>r6F6vcd$I>uN0-|MWJhE|c<0mG~rC50$-C;z)P7^db0s{fx(o z@Ot&Sz)JZ=ln1kzWA(3TSjZ|$S>!5OWDcnR&I>f`a(Alm4;vQ$y=s0 z{IZqfXs=#f#9F&}VsD8aN91dl$_{>gdzaInQLQl`qv;(rt4jRdP>PE9vA4%wtc@JU zatv`yPuPh?$R)R(sh*+BmQ9_?ajc7c*b#b+>D&@Ov)I(kQh)$=l=r8m{;+xyVTTi= z=|4LSApIc8K;~KvopAVkS%{<`~33}>5E@j-C4K!$Yam{0z&9NttK1KxDr|CJs8&m*5qlRU-!5ij{p-k&Lc{kIEWG$rcA z}m4D^SqobzdASnJa_Z8fnccTxpSDN;J|;S;eYYFi+U%| z{kExp_Mh%a|7~plIXnN{7cj}rfBkU^jF<73OwGUlu{TjKPHxs>Tc73^G7bNE7Vn5HuIU?{iz@GpF@^nlp)>7nPyTobtd}@DE|uq&?pn}y6C|Mo3q zNMqN;WwdCn{QKqpe*gd1@5mcY(MSe>y59fx9vV1pY;63P&*up#*!1^@dJ)*dT3WF* zJeXtYTk*}m@~Hpm?7!wpp^*eOa0UDP?@#SrU<03R=H>kD4Xo(zygKx0hc7lI`0X!R z*ndn%#+wtPwW5x^#P;B!$!}X7a#9sWPEOZwH()&{v;FcB{?A@uyOT05QGRhh?oQqL zAIf{bF#zD+K<^;)Tp+6!V9_P}+lwU#P#0tMhqASGH~seCzB*ak4?}}r|HkwFIqHlm zKXd%>$#}seX)pNgyo5Hl9<_(p4bNgZ{EH=?cn_G z7bK&q)QRJF)Ii?nymPjQLVt9ClnNv5OBA+wy_lAsPEEJ-j!Y@DE2Ofk>2}fGF&=e6 z?gN+Vo;V>x6pk&G>(%Zsn}-uhi_J}+tGc*(b7(eHLv=HYY-lM}ITideW@SUje!@0+ z9p?=duqbTTPLu$*iGh583_-ehLE*NTN*?z7@=q6f%pX$J>{hoC@XUeb*dH(YuG;L3 z%gu%KewI$CZ&9>>4O}#Ru`f!kFh@(;KF?5dZKPVx(X@Zdwv+=Cc*;xsN{nxT0TY$; znzb^xqsix_gz?7?uPHXUe#mX$;&_8ew(zl+4u8xAs_7VZcp8x(PyJCAr*_R0U6Jjo z>MmycWsajQGT^-Tj#=E!2p!U#%^=^huHp@?>Tdjm#9{2=9#V&c+DbW2$f@K_U?8hA zyOntYc8{>f1~csd@_T!DSKM8;7bWiT!kS2Gijn1m_ik;S@R=UIn7v-q2Oqw|H4`6H z6_rwBkftFs=={wMrKX>?Z2}|&Z~xeGtIc2k(#5nglnQw3DUPq}r$+eBrf?qausV66 zTbCF5CU4?5uCIl(hcdWvzr-esD~m_6cWV}gUr-Ta2ExZz%J|vTN6O;N9LJjzT>4&^ zD9QY$m$g98qrt+gHPwLF&6IxLOnLdDEr>$z+K4GEx&TO-E&25`GZ$I)PPn9DW3JUV z`Wzly&vAl<5J7cy*4#H@*Q-n2kj#{adO+oEW9$IRUuls26|DG_A-CTNd~3A5D0*yW zqScp_)1U;RldNGu6%8u-CnmeRSZ1*mIKb7m}$eQ$Pk z1eddi12T!@KrzVnOP2eQBc?K|kVcXRu3B$>b#?g2=cI&C)`0H|tL;%?@wv@&-ir{P zh%MsqiBLv(dXgp@gi}|)dPbRB*1bpY(uFLq_vD&OoiEEk2`D8Ul(*-2KLBfVkoi;q zx%iEJP>iLk(d5MZoT`Ia)9gzYsS+TVW%jDb-wCB#>)&&~?wl&k7gvFtLgbtECCW*7 zTf8}`Mj5(I{M^}j%E-df)*~W2oBimIANd&nGM??0IcQRZ_wlCC;?hkUk#*O_ReOEY z?5kr@0t(k^S4(u)_$T9Oc!#?HO2fCAvL!Y!7w#hzB9XA5xR*54e$Lsuci%F`(M*1P z#4kF>LCF&eelV}#ByoConNNDe={jd*JsuNi`X$+*Wk8xhva8gooKR`+RAP)1RsJl| zPtb={fDjdrCR{e=oDVh#4^-2SSLf={bVdvKEQuqVooj4*xodpp zS%f`Nv6lD8%i-$$3T{AaC2Z&Drl=y!C5qz%nWIO{3*STL<$R|PUn*V{Z1hcTyLfGZj zAbCa_W~y5fobhHZd(n146@q!P8VD-pqs?CZ8?hylq>o*1MD}o=Nz1G1ql4rn*b4R~G z`Ak^~PngXw6)ZWVtOEt#4_NmS{CM|pRo1~dU+0qa3p8UY^d4fa@>|+YOI2>Fv;{ljP=KKK z%Yc0SO6k62aT@~*l)xW`Jg;92ucY=N65C;{^V8Sr0jZFNzC*iuvQ?W;4fd-x8I$tZ z5ylCor=hf^Z`xoshi>{C>neZjLO4dy-EkObxFhGfT1!|qHA+6_qMP();P&BlOL)O?mV zLu3Nxfr@PJ5iOmN?Y^uU6gBuT$8%F4%l=q}q+3V3In4E7XOd_BG@k3&E=p{Fg*xk_ zIlHaZY0otuw@R$r|W7VKbTXoX0tt{+FLDp|vGS4n*; zKyVElYK46<53%9~HM0M#pZAV>KL;)`RP#=PD(}lgvvo&c1U4{{y65a zMvp}~j(c;me21nASZv(Mq6*XW*gpXoUa}V2Gx2lYD|-ayr1f196~!q$9e1U3U<^t~~mH|Gq}|XZSmL;K(|>kiCpiZ}gWitj&Fq!^vbo zbLXHy%AKoahIU>oW~o1ZZBIZ6-&<;M(@P7ZgDTH%3D{IjI{umSFSSBGrdA*LwvX+M zYnJCr5p9c8@wZO}!<6H<^h1dYH_K9)75qZQW{v}XzSV(QJ>3qr2ogEFp zo}Aloju;_jL@n>$dX-%-pn5pn^HUe?jbD?Qzz9CI<*DgLAj3!HtF^X^?16@jbzDHD zga5PF#{vhbm?yOWo5F6iVxv}jFxHAS zRxuljJTwJSzsZE&Le)*dbJc29YQh$ulN7c=Jh~}HVW;Ys0~=UqXFVUtWY_q5?ccZ1 zBs9xgUjrQ*(HSyu)Vd-c#0)NNiDvpD>BCPjOAYgl`n&sT-~|BsAkge9Vuv|_tPmJQ zY<5Xu%OjUSy3l!v2k4@P*sukovB)YGC*INHDXdc|OR>KrdVSg!6rID@$m<`f8~_O- zdv86E?2`psT`#Arkf@ayO|Rsvl&H)_v_pMgibEK9C+m)5PR>dNOG1E(gcGqo`T(=k z&C@k9>byz2k^_CNnU6zMlX=ngR@Ax@o>b>)Q|B0z2T@f{%GJ7q!QT67A48XqhAe=VP*JY4AhHX zC*m*A&XGc_Std_#cCS9i7%+UV8@2Y^55QIk_R}EbeCfN2!S)C6*Pz)v&YCe#_!uP2HWJg zVIo~^8p_RC7Vxq2^PyUEkICJ}w#gOEyZbFC3OtAZ7iX|SCqmk#QIkp*FRwkf?ml-Y9)RF4U7-(&W| z*zPt@f*x{%f@$Y>rnc$tSL3}P%QpIkqSMFwd={__NSplI-Ni(yJ^=W*@Q!w5UK}G3 z>$Z||1Vk(Ai47vMAB<%RPJIhZ+^H~#otv_feX?k52syl^YDk5UhEDLL!XNq0?^^>8 z^xW8DVi?}n=R@qh35L*#vorV#j^|rHD==Rv_btv2!HvP-0$ezp?^2I8^}@kyJvLU5 z@<^}7_H9n>F?RD1nKV+%V_M)s`}v>z&Hs|Ykm?|}oTDdPc#uIN*{^Nbv5tzV#e6f5 zv!0sO802Y_q`_9yS)Fbb8$mx9T)k6n>6-KGUL2npFA=*ZSHIW@*A?Y))BBERRuyB# zWSr#{%<3gKUpvvEInz^` z0Ol6h@3^py+IqGaFRu(s1zJYqFiFS4YLYXPYxb;0y{oTMhZ^*6W?MC ztzEE14&~IB&h$5OJFRv5eC%ETn<(|4&rr@LWyfmMsDh*NirAO=L3?Lqby0hlOAF>k zH04HYiX3p`R|yw0o3*Zd0>X~Tm+mVKqsj<QZeB&&?^F_Cf&qSxiU}vfC)L(s+jCwKKO(FaRMEY`j3`KNW@eKR8?TX>BQIeJzA{_*y#_#eGiZCNqsa|4yO?2^@i|t&=oqRle<5b(KgDb~E#`wgutC%E zDOs(mGC$^Xwl?aSV{Qym?xlBH3Ns3wiv8-#kj*hoH4egLTE{q6CsE`GajhV3{h9pVe;Df?K>g>MzElCd@ zzK)HV*c|6|wJGmdRa%8LWpPcKR$h%vGg&UDZ}en{;nx1T_4P6UolqkJBL{MNpj)Fd zEQ;}W(%Zq7g{Y9qnW(wZbt%{r^t`@@^t!tw0R zX@lxVc??R_YuvW(u_`AlR&7-E~Ocuvk@~<>QjM z8}^|aV)}0J?eU*#pjqij1xP*;+2(tMLtQBL(e`;DZC})g4h;qz4-2|l)vsq`-BW!* ztQ>KO!fw}FwXx?_7#jHgID4J*9z^UY!?v_Ub39Wa5W|bBA8Sg$PnL!I_oK>$JUC5^ zjWZBT`ijv#QyM8fa~`EVu3m@HZh{f10XVOXbPm3TcqWjpzc{VYYTnBAPWyAcPtfW! z{v}3(bM6R%4wr8nj}!+i>q3b56`=x?t1pWBl+v0*Xl*mbC;0K%=0s>sXZF48hBVwx zOI+LInIrmc9SZ&Ey|L(F8+b}j%#3?CMH=cxkB-Muj{R;23D#36p(&$J+%o~wFL8ru zBv0c5{OQda^cv{2SAGnD){LQ=p;<)@+M1u_9`bqg??06w7{>>f@rrrGq-hv!&l2^! zE5gMbd%Sj|T}nSnRBRNNDKRAMnJWt>2)xhj_iI+Z#_Gl3l>;_p;FV>s zw8)&||6ZKlSDjsJT&z|C0oR*KgGTS4KSW)9l^pxTT`LyWs(f>czlwcuIW4KYqoWE! zQ#q|VN&3#JV#}l*(j9IXBT85UxZyeQ`hzDxjsmIMs4Gc!Pw$Igr%~=rf|3&Q{9N{& z#2HC_v3T^E8?J*`D_`cEdE8Cb;YmcCNxycSS_{GSva#E1stAj}!`^Q@NFA88 zd8ykuOB#S*0rh==K#ep#?aiOamtz738Nz4Yd#RUr4S@YG-zs3Z*jr(JU0jIEb<#y+ zN!?9ut$h8VTZKo*gVADswJh_2vU&jCYlRT{ltxs;_JY2GIKTy`#zjl6n<6ElUHLMd zf_`-G*)enpyl5IH?!59vSOrWs(VFyqZ!NDYeu+t=txQ=3Yn(D7jWi$^Jq zAw#>&*{fxNF9Fb!rk@lL!zVRCXY#ReMpxb5btAkmxLX>0%o8$vRFg7%t`p3|Nm3Wo{rA-_gQF(UJL8rEie(D zO}o^TB15+XzffA@JSl_p>UG}At18vL#-%!@8N(0DVhEEg_4$%2(~lNdKXc`%i;v_? z!mMfU5Mq9(-P?R;x_0K+#H@RCvu}WQWh3vdo3Eh>&iW+j14|rmn%c@}u7gOTgSAKc z8P!<5XLnkd5EqxO4qGAm$!9}$fJ=G*K5)R+L+d-r@uDSoSZ(&VArJNUcG z(Q@8zXO6rnN{LZOyOFPlD{=vjEJqig;bhSJy59rL1uIg1(PlN$Dbcsn7_ei|j{(O?LowoRj?4cl!>*H@aIYSB-Q zJTO#xpjP8WZDp>&6>@XRS}A)%ncYC&pilQWv-GI8azuZ3$cCxs#z)_S7xwkl71%9a z8)ZGgoHtpym2P?mcm`z_S;A{VR5MAE%}Bm!UICjCgkE&XVY3B@gGs>{ubNshcaY5> z&)agv(vo9TG4VBi8&jl(VVK*~26G1XltrHIXi@1XH=#zvM!NLp_*+inT`zz}2024H z1VZ1=RDi_Z)JJ7MivV5FCjbQ8dRjt9jbxqRVbZ(S$9>&tlWE$cU${|lbU23Kg}x6< zSx=$epIFS1U}4;Q`?5%(kWM%wC+Y(ma}XI=qYlUJfk(eo-T&iamNK*C!iZ3!Vg|1D zI6_|}u4R(Oc+zdl+>D+uLhA2>ZhhmPEx6e|t~{{p1cnOwlemuFqukfGN1UOp`qX{3 z;}Ym1KxLaPxzZ6WAh@DJ@-5&+SM-O3Hcz18TTp`=;6Hz{in-i6Pb^tf`dVbOWC%Cd zjJ;m+Ovq+xz+NzJlXkei)wCiRbXw+C_5HWSWEoK$)YnPZHo}On_OcYV!-BmVwU9En zBkM*`4OL|)ZsXGgGbmXst+GrVaNg$=`{tMxGL^b(6J6Y782DV-qT5I$HMRUb;&W6L zCZpYg$nN4fJnJ77^y|cDYB0bmwV@RC-9w8U^$CeC1aFg=*Qa+UUqH+NU-$;6e^lDr zdE)bE5AQ&`TVhq($DaqfW5+*@YWygRCa+&hL)e z@W{Y3t zktg+yxC69MR&`KRX0dbU=_H)v6; z_If?03CN_Q$qlStg5^LK;loz55x7kJaGarV`;d`t?aCFj4nOr8P>U>0NLmEyO9hIc z##onnSIYO!7D8R0#1km8dV!dc@wuXRGyx-LB^|xXqC_3S=*Y zvG_0FL2r~!zlydg&ukM%X&x7OTulP>n*O}};KgS$iFIe_ z5pij_BOMON;Y?h97}w;Lkes8OX>UO@>X&A8wfBiufxH>t)JFAQFNCbFeRQ_cfdOnC zk46`?9p?(`^UroB7Xoc38l8ySfExVxYWh{L2`muObboD?Ot8bzo1Cfea#l`_dWT+% z|0Gbg7kF-YRw9xt008iBxYSG*eXH@gP|`iNL!F;Lu_Nha6>S6Vu^em<6V*+x2kGee zJTQrN66sA4bX{v;-)dUygf*f@TE$q8b?RBBD-83k8ttz4dg~6Tw5foVSuKv;&tPCF z&4I3h8ie5ZF$-!eB)`Ibh6XeY=m!bMq37+&Xi=rH`j^kzm*cBqfCcFYiJEXpvL^tU zr-y-?qj}IOL-;y8#7k*7Wsc+wl`xnjXQ4BxTalv(+<3gh8t3%AI{VoEm4yqXDd%4; zqyGWq{I}GK)Wns6I8MM%Rnr!D<$xLPKk;)zOUURh(Bg8Zo;BvwiDO6xbM7HzNa!|G zVn;PtI)F^kRDx2yYXPltLJ`m8W=H@O+-7>O6uy~B#yio>iOW3t&h&Ic$vnp&Ld%%m z3f{_UZa?M^m=8WjlmV#rnb{iy^BkfaQ=vhoYMA-FUPO7XhB6`1)A%akvgc@Gbyk8o ztS9n8dg(`Vo6_zpn%i#>6|Z(wTwl<8?fX9t@ZesW@IBrGE#IIjv)dd-T&3hJC-Fu< zNT*R#OXIiFQb8%WBh$>U7P4E!SK3d0uNNM45j~|K>bj0FtgxL-UXgGHkii4j2J-u& zY({|fLl|GM+69uzB@VD_5eUs0I7%FOn?v`D{$V|4ax$W3n9)I~ z(9y9{;+V+-v$Cqqsp*R<6ebFbU2sqfpL3DpKsR!}=2uBI=qr?pnShkiE`YMIy@xuoCOmsO2=sq0 zSv4`)I(*B*RBI=YqSF6(2D{l1W9%{3#hXVnSU%;cU^qUT)rvET)7S@+OR#g=HHJJN^Du|NY*!?8-wSsuPaB?PIdvgvj_k~ z&c}_r0h7{B(w-gMQW3>hbKsCSxjZGuu+rV4CZ&6|_~$=U67nCoGO(b1Db-^w*`mOo z8F$*MvhS8mb`SmW>SOAZRKw^7VbA=-BlryOZd6QSFl5V$RUjg!$WPdu;8Tmz5&~MhvJ%OB7dCeF95J z{y@N9;WjtQrTGr5wwKS^beU3~`aF}L>A{JZsfda)E6UXbXFr#o_qt04ImIx%X-nNWZvJ&v3Kj_PSHo-XlXkqT+%A zKWRf5C2CIt4hU-FU|9H$^fqs6L` z$+c!}aHk$E%n_!(xYkmE+4B8=hd$Eqlax)sNB0)bcaoqy5X(i%9s_Z zC{*#z+bAv#lBt`zG*jg(kgxm$dfBgM0NfGEorU|+XZ&My@%KDE5LghtQGi)~NjV0G zzxXLcuSy4i?Iosl=$10y_I=#Ltdp>g)7iO2k*BGZ+7CM2Y&a~ObAG4=?j zUz6=I><5$Tg8H_f&Yw{Gz)}V^uRdGmEn<}mE4OG|POK>kn!XM|0=|xyS@auZCr>_Q zQM8zU+tsRv&nlQqeCfCx1hs=ruOu5wu)#q{h7Mj|gX89A{|#gjMESbp^w}oQ#op(; zo!@vAg}{2NN~K?2SGU9Xt<+~`w#u0Nq{z>jcEvW6My;;rCbjnBdHG*`R%pkh!34cx z&ac7}uo)d4vPdPOB111FnYf2O`E?JhgDFJZke{VxaZKkaNl`DlqS(wzytgLm+imS% zt#dWh$UVwKT(BKsECmcCU*MYZmQ@zh9WmebIfKSA8@rjp0!yRub1eqgFQYl(Xo4Q! z6S&o!XhKE*$FpA^h>3|cB{w6l(Yx-n+rw)zJCDSH(v?^pit|{rJV7&}kU027BdKm{JR9G*2&QT@_NV9 z5*mo*<-N1B9Ig}U?ed<#cG;)YYexD}a4o?zTe=j;mquVE;%9r*XC*=#1SgIwURB!Y z+ab#j4Sh@^$1_Y0cK4%Pnvy?VwmPmO5otLQi{SY~;3gcgNiS&l*cXrZ zgLNC0qz|YjV_{AG zQbD4OQrQwz8C6B4*a&^*A&&cPUcnPY%9(lNA2zH!>)W@>3$?Wn{?JuDBJ$+|a#Ojx z9gD_=h+FqkXd=G0fX_rFihK15FMj?={ze2q?UXh)%Bv5zp3yqE3A2aK_5%s6$aZ>< zXA+f(l67I5m>HM#%-X0_dmy4zXf#mqB$XY6hr(?ZS>G;dah3m+lPX4oGg?Dp-h7I z<9BE~fI_el;F$Jtf6%Xl4L+4Y^7z8Pr+W<~v_WWS${wKkdi8tb-z$&Q+w{{9ZWPEA zY~*}6UFur-`Yrleet4n{?l9nioCIZk!<%GXi@rnwsDgm3itqWdmwV=H>M4F>+Ktqr zv#lG@spa;~kefl%eNagr-GZEHbRCeZW;xhh*db>eUR@Q{ZiZ6L%#12J`R;dIVlxvL zDmCrf(2FJ$3R>av8MNw^q!*PBy(MW+{Ems~PCB4q48KSz+VJ*1Q_ zv^@2O%*T2#Kj9XAU4Q%%xI!D=lQdGmspTK3S7>Vi6awWHY$e^YI-j7|?{vQ+R4Dgc9X@h_UK{IP`is8$3;ax5Lg(mOC#u=K`}I-m=f<% zvDGV-btLBia1vyn`v=qT1x@q&ZKy^8ch*J{jdPEDSKF+Lk3+_v)%2nR0l`k6=T4eT zA}-2caMl2FRrd5H+ua|v4fjXwIo+VX zw??4bgToE+i-(?(e=<2!78i2Vc6XK|l-$5|Q5iiB?@>pctt?V`%jQd?+VBAJ#4OAJr)>o5b*C1an zA|%@T$dKXoNr_>Ur-Ik*=no6Hm(JApVekw7mS=IQ%)MDwr483aw<`dcZQ>TPPH6hT zcmnWH^m@wS^=#ZNi(^!hmngN++<<}=zqVGnel~@R#cLM}a`bh&!$FIPy1?^mp5I@e z?sZS7v=zX5sFL+tojyCcxKcdt8pV7<+mJd%98ZaB!zn3Y78V-`+@fxq;cD3`3D{!E zBOR_y5eaUa(Ly1na?4SExww7ehhq9bGQ$5Z#fpV3rPj>O3^$F?5%pkygARWJc>Wza zoc~(VPvIDL=e}uu$VcIu!!8`wHMYzC!UYTN(^aF6J|{Yt#r{JVJA>nXx{OI`RQ?t^ohW2=}fEo zlws9`;kVI3m-;K*S8k47Ux@|cx2TA1Cm;yjxB4 zFLMFqCTY1<7oibZ5PILEuQFK%jJ^^lkQp_2&XDf(@q0@Rn4*@fe1%)KPV$YtHjck=ibxbO(qENcj^+A{?J|O!@<0t-i-md2F0?ajMOrSk!QN)?0V2R;-ih4H ze;>yNX%7YAtC1p2t{L>4iNuuPow)&tp7=(iUL!J~no5wnsuey_ceZ;0Z^%WlDP zFrnxq>15bTRB3g}oSI{@4@ku%fpr8yOT#1umY5z*GOEaF5`+7-b!Ml1)_QB}4!=r$ zsM=-*tzYY1oEmpJ(LpIWZX)sk@RieuUe6D6t=<*2H{qbEyBr#Xm+|}`t#GL4TfGwN zN;d_<0I-&Mg;FB#Bm2gJ)Euf6LS(*vqcs1y+|bDeC#*Z(&5M)!{+@ARJ-|C(nEl?e zw2yl@IICiqIRir^o&SPyrMygUc{%_?bK|C1Zga7xQ%u_1b8;27+Pwl*lL0S^w$6?v z^4n#t^m4Cj5bm(%b7s*h+MF2%suUU{j6fo6UisF&Kg%cn=N7(9S9<9ZC2?pH*c76< zuZ#tA zhU6BIf2uD3OPXefl;6Rq~nEalm3vf!z;_^qj0-#_MU zvU20c9DYZm!XEGP&?_9A{GGw46_K`mC1rvC|tA`ql1F zD`^1zMM7yi8{N2fRQt9q8bJGZ0NBfg+0+)tq4+LQK;(j@>i!)HA~!%WDhA<&?HWvP zzw1?D8_s8OftoXJ^t7|JbJ87gh3FnY}H;`3PxY3eTnOFFpz>-WF*onPEiQqHso zbO;@>oP_R5?B+pm5|EwVK&pZAx7vxueP}Dz9 z=_a!N=4;j~CVueXL7FzeQLQs(Al7^Mn}7c%2;j%sb^xTwR7Z$I@^23ORqMHn`yQ>5 zq^JJNkbd@~e;IcQ(8uidHebPvS|Y=5KD6ErF$UnbYSxkdHsMl=_WDELqq-GfdGY%^ zb@2Sn0sBeSIIlhiDWdyKi2l#x{C_y?W#@_GH`M@IzSUvq9O_rM;Xj}2#dNA8#V-7{ zWM29MMy+!vB6|_FTI#r^=S*%$k^NJE%#YD#aQVM~{|b;wQ{}Z#8#{uc?60NTW@MMVKI0#FUak(q>{8Iz7bT-TJ`M5F8@PswkOW14+T&d-t8xK zuKv|R?q9ayfBH^JmfUhXyUogS&}v4&XI}MM(i)(Er{F>L%J#=q!x>*4E?B{Iv)x!> z7MEvNevwIi_mR{*Kfl4FkGC2>1%D4O=b({{Xl?KNYuXE&tZahZxZ?jv{N6D^Fk{`XZZ)_>1M^y$8&kAm6PX__b9bQ+)!g?`EMRUMLUxKoM(m*)N7Z=1t&k(!!GWW?+78bkc=tAmi=l>vDAf^b$~ ziqoDL{?d#8H>*5*nf!-Xh5@nng-(ocJwx0d)>pLHL0JM|a0U`DQ=`QiC< z=OW&#$KGMQ_qP^+IQyBubPxUcIc6{5yypflsHS_q(4I*BC_KYTzs?Bf(PabGX)-8w6|LjgHZN_2A{!BC7 zKA?doAa2%cUuHbQunS-FHHB}90}-)wCjiH~(g9Ur*UY{5q6okfw9*TEsxNWvH(P;* zz9gFhbP_;47$}ApN$FB(~WuP#I-5s z^md=EtJq>^-&^h6M@I-7P-P4b132p^f#PHNnKI*44|NGrnP5Xt%&9r%}(Y-WtLR5ws! zss?oCU~sqqj`kaYklbhkLrMTtXf}`hMvJu>#q_j0V9Kb4ibsJ|-2ebT{G_0aO}LPP z{3LVs`ei}`Z!P+0smQ(Y`0jFj&&&hMr>Fd9$yY3l!6D4sd=HcVQq+)=J?DM~?7BYH zOzK|4BR^S|VY;1t^l2+@*}$1W1IVG@K1o3hnip}F5^HW8;UJZ7h$YbwgO+!YGB<&4 zU2AxFzIKUwS+%Btw^`LeODZDEmr=La(%`i(-Aw@4ybGj&HuZZPCoC8|Nr5)82T@nw z;L4ve7;-Qf-uh!Uo9D*FpZnMQY}HJq!OD!N!EE-?U=etEt7P*lgbGFF25?V|+i;tZ z#zd?-G{DfZu2G4jx)1k<_0TZQ(nmqNQHN`NakpuPvLTi0-`HS_neZnMH`OFOW^%kV zpEL>?XlO5g&*Qh5>Hzd&7WB}NH~@gAPv6j3VA{QQ42f$9mAU!%nf5A&^bf+`RHoy6 z6*=RpMRLog#W2m8FeTjzT)ib_GR?p;8-!sS3g~3a&(y_VNdbT#J8d_F%@a?UjCvl#>q7RtzOd4WqW#MQjg8_! z$&dQIFtZ=B0aaUh1&4j+Zk3bS+c*3uK%+u+gDMm zND=;hwNiiUVm@Eo`ptYyGfyKx4CAXdD}nf~RQWF6>e$CYvJ49h1#ukN`5P&v%WY-? zdvJ*B4~wpJ-{T%N88E;g(t~|U+#*3T&sSW zLR&tZSuV26F!Qdw>v)VT@UMg0rmNwm!ttKyd}1|H6boJkTTGAdi$nWGu~Sa{!q_P! zczGI|j2G<>XnCWxIv!()jZK6qc*F-V4#(<#``FR(kv>f&@~y>l&}6~m>?f!Xc8l^e z>-ygc-H-?sZo_J0c*LW*Zct-P1*kq^0~bX%_J!)M6!CM?Ximf1A;~_2Pp0--PtSwK z=?1sFqnwshpyHbGV)*dgc<|*e#=jU5JTh9>BZ2wW3YsHS{TuUmOn)u{L2cYV6s0O`8ZH?;n? zsP7>USVb=9c|qJM-ng?8~hZlaZNgQwef`ll+t zC)N5Qv3G%X2U%Ldi-AZtmI#R>V|boU_3LYIjm=h(9GSfw&o5k1OkWrL7A#flJ|1)SXFHoQ zlRj}ziSLG$P#7sv&Us|N$WfQ3&)1OIUF>861Y}~+H;==1)(ARV3HIS7Ya;XJO9*(5 zTK4e%ltWzZ|Ksc{z@qH7wk4#Ml9rZ`M!FG@mJp;vL`u4I2muKx>F!Pe>Fy4xp*tjp z9$<+7!T0r?^L^hr=YP++uDRwKAI5q1vt#YG*L|;hmA)K4;+H@_Jo^yi zg}PIyXW4=|>+a~T$w*36O2ciWBgrk+JZp#}WL)tTTR*+y$4O4ja+Zd(9rGR)Wx_>` zBp$Qu1D~4hdhKdU@Fzw4$G6jsuNKrrA{Ak0VO9G|3j^;Lu+f1@h4|`0=DBLY8|4e4 zCtUcna5xme%f~!WR7WCh^AK12n$M`4$xNrERIx2*JFaXany7N07Q;A!4Ve&Q9^kjE z*U{80kZA*q8X|sGB@GRYkW7`_k>IZc+DPr1Hr~wKvhxb?z`A*cMGk)${Jy;>BZWu1 zg^H_4U3_fvaFrp#U8P})ReOaFF;yfV%aJ+NGIvhU_Ba~j(y7*xoYD`-TrvTJXxP%- zD~UO|+efZlPp*J9Q??kzyX*riGN4|sq!iz`!uo7|{1cnZx7vvs_x^5wydnlsv$L1% z`<~J?+z+A{s>>H)k)26hifc|aHB`4li$GKu=~9prh4<(db-?4PE{14k=A|&goN-3= zvKafV5qCczZSQ@I*)YpiVP9Cv>?^6p*3Wo_rR9Y&46^ZVD+eQ3PS6bGgSfqyZe1Lf zNLL|N{Yf+u3JL)TSjs|E>t;ePag2a+4dkPhEoR|zK+o>_ik5{Vxji)%;0n9g`7+`b zQXr%U!zO+7^KgZl>~c7G5z;(cgu244)$;sH+)e2hW=*mxhbh}!@`5ApC(Jl5h!i2O z+LQ9xLtedq!*6l?JwfdvfySPeIgoSXTQYQx3bu%KU(ADT%3Pq|m7Mw*zML3S^^BL> zWiN@_KCCgTGszeS)W8BkJFv7`RfmACt4#|6dOpfelM8-J>j5E0?UGCuF_z3W88vD8 zs&mjh=E~H7IHl|!HO2AGy-!4xrr<=RxbnNaqajWNmE--IFZWaCgCvD;rlLJPD(N{X zCT;vzV~h+$7QIGOH3U7qW{(-_;t^`hx8Mxp*9a<;9jX*+bz*$F7?`>W;byr9+Z-l) z;xxuz1z=YFHZp&XUeN0Y841a(y=-i-VB+FO{sxCtwl_T%DrsJ4q062qu!DfKJyDt| zeaoY#_(AW@#lFuaA!fBo<>BCXyuYvE^C4b z3TC`K+9XRU2G0mmSwW&G!!okjv`XonDlUjCg&0rbX(A zFWMWnVAjsZKQoh%Rl?!b)pJK~yQpEl&_$pEZ(?Y?_wxQrx6Nc%WBU*zyT-V#pU*e| zOG?}?@@Mw{U;IYC{o*4(r{zaj$4O%x_FA}!Qx6f@tf}+HX zx;s_{m+!bL8GwpAAIEQTCLv|-c}5%rFB0VkQ8>?C_OJq)<>6jKD z`S4FVlz-TnU-L$6+3ij!PF?|_;U%y}I}ww`=^EIPBlg+&bxwwjJ=ouEN z{?s?*cQ~44Ylt7clMdZ6j$(od&EnEaq|?f?ptX`DCE)>Qpj7L{2`gd&px%mJO);!@n5k^yzwX9rfBw}B zr#2OJ`HmdlQ%HQd{Lc;heh>dNbZi8PIX22fOg~z|>aR||5sg>#YkheE=l9(E47QG5 zP(tQmRd;D@qTI5b_7(-%F#afo#Zqe_x6e1-;imibo8!_|+5tz+Ix)>85!Wku*P8L9 zPej4p5hlg4#|&31ts{elOB;aFlhJgqGJAh^kaSkN3}@ii5sW|ACW>DxAbqtFQw@Mn zzks!6IMBn&BSQ`p-i3qL`RXkPS!5YtTScqO>v8_?{MBAud+wLJWlho_J3LcZ8{|FT zGu@wr9$F8v)`B|*U$CDKf&Oqu?%zc{P!FLx9;g+o%XVqjoU9V&{`CYS{?x6Z+-=kMv4TOb96-0s+t z05?Aqf46neBKY_`7021FxX0w-V%!~c$YxHW%g*Rp50g$Ifs$u4nD6V;vtYcYp=w`5 zTDcOfhQ&>x;`YuCtjk_`g)}zTdMQp(ZCvl zN;O6#ve8^E!n(~_<*rV*m6&9T0oO$B@DiFKE;ELF5dC*wZB@*>WouO|)Dd{R(pT^S z;ZMs09$F`tqtdY-ksB7d2>X)?+f7XM@SaB$wNr;|>D4>PC?4oHdiXP|WLTIz*WMv( zxGg%yalSk@YSPb(8-+2dA3yKrD-%OA8IG2zcXAP*b>1(X`xId^Q5!VYD08Y&vmnD1 z^e*+sYZcsFd4fPaO0-$vcvY;^G-ZJksFp$*w~s`7-x_oHyIT?vkOcIRnjskdiNqT0 z=Qt}OxC2O8*mgD_cG7A(ZM5f-bo+VumHjxv$5e8$eZ-7oYr5iaPX{1nG~FKhP8J{H zl8M|2c|6Nj4#HWz(YqCN-7BZCU0v@ZG%O#6mkO6$T8l`7ZB94wEjbvnnBdx7U!b<# zOwNgcSWm3db^-U}i28v6uW-RC7{mN;-g|^-J63Hr()hcY%>hPBAmzmwzC0IOGgsEp zcgR_85N4S%)csCB2Pn63m8JeFy_ZnHtU{;J<%gBMT&u2INh0R#>tP#+eJPrBIW`B1 z*>5Lj9>wG2CcFZu%7(bDHpQg5&K1|D<)cJR+ieP={8l) zY%A!71`Y>B2+qXxT_8UKyZki|l5Jl38ycY|9jnFq*Vb2#ZB!}}6xV~1G?nuz$1Ewx zaNFcbH9xgZOHBl)`%EeG+31+zS&$f#WoAaykcDWVW7K#bR<%}KV`+{Y7VxZ z_`xR`nzBrJ)meE}<16wu^%OqsDe<7EW-Q=KY~b($rA_t)OMQ>ndF3xZPNQ6UPD~SK zj@&jaje}<|zFY5zopK&*6&M3q7@Sw6q==b77jSG2R&GR^xAVmY33s0#9E)XdHN1vg zS@k5agWSR`wm@Tblzj68$pDE1QMxtiK_i@aI{87u5Z7;S1rA5r6H$v^@x39fLTn4> zO_l&S%i1eJ_*N=hY1gW$yV%$eMTO0Hb;S5B){7xRBnX=+RCE$1AG=$j6(h^NM05ZG z0wUaZ89S2}{1Fm;0$=35Y$bNlC-OUfSEA{bH2$-l2 zUXq`6Q+>X4W1qP0>xO6lglZ5FoU-I0ln&~emObD~+3QtMX zx@1q;)z=No@i+87dovX?sdx5oIn6k9aN=97yT6w6sdQshKS@TQcprs|8Zx?%)f#_X zdqAvc3M~pGz*20Fr4LVcJ(+(`ElW{WEIu0K$kTy-Nv10xyD#};t%dyYwGM?_FaU}b zttJxeanzerGvM}!Sk7bOEtwesv&R^waTa!%kQ=&ReL)K>s6{|h1gKj( zm~f45Q|X545KbzvqP%3eG1{Vxi#1ps5(dlevu6=^WVNsE;{>*tYgEyTu)C2Dbk}|Y z>$+b1F{j&OG8W=Tz>Zf)d%o`|E)Ziqi9BqUnEij`re!uYG#g#XiIUv@Uh zK*8_+tl>2)NV^~vcB3#d0T!=9BKw}`FQ&CY3Q@FTX~>NZ4QuCf*TU0Jl}iiMivn0Q zVuCklEN3}$HJd_q`8qL#Yi6)fhR{dstemv`#iqZRReF96g6L{!)ZQL!s9BXknDpe^ zJKE<9w*~D}j}+B&Cl*!}2kmd$A8J-w`EKqBLWD`SknZPs?PHX86gxLHOOdgb{6Dk0 z#Ain#lCr3d`sYRg6CFR=X$JO;QIy%TX5#=>6Sdk3UHgekfP2eZ{}46=f9R6BvfbvP zm;U*p*P>uu&Xo9%REee<`;O6=KZZo+kI+LvpFzZ?dKcWU|d_&=GZQ!L1sZ zMijL3ML+kmlcA(wRGDCIGPh;V7MRS>(74F~VZTZawH+(P5td(`@^4R2It&qT(fLyG z&VvBE@Em2`E~Mr?{2k!AI1oDOgKQO~C5RwLv#<%6Bu8q)$04o0{8atWw=E*G?4mhn z8|&kDpc0-oGf^Pe{+gW>hd^vp6yr=wa85^ldNnO?D7yQMTm^!L;QpFC&cxxgXyZf? z{eVVlvi3r*tOl(6P-O3}@ADb_Hva&ybahM+?RZOTYGWlCtRsC~A{;tY%XNshN2_D5 zoi{|xz#F=Z&DU2A*e||WE7mZOxxQsoKde1)1E!383j16+?F)-_`f$gs{xt2H-9YKl zX}|XSNqAki3R?WyQamyy#O%b4-wNv zd_7se=|{KKkZ%zi(#ppQsheOvVSXcR2k3KFGS@By9AcK98{&EbCF~_)%XCUiFbP+- zP&U-AR3q9)N=auwuFx5~P{sYgIh@=&o>6&=zCt>)7n zFJ1chP%PF?uXo*S9uyDBNY_YzFmHix>;jj*$ZAE2b^70*A zUUj|teaOlR9t?&5h+kV?U*(~{^qPnTaLw-BF$#7RRTh0UOpNA>L6sMBLJjvpp~Zdg zk$`-d8J0`WsR{}H)1*w#j^_})Ki)V|w zHi%EO*Xie$Cp*oV)8c|ua%bp?7TnHbq{s>nbeXbuU1KUq0zbdQ@}XLPfdTuRz7v~d z=r%U~@IGd?Tu<}PffK3K!cnM1r6^bP(MQyP51Rl6V~=e1qduin#BuX!n>#nJW>A@K zE!K0~i7GC_B!2s9Vge9XJVTJ0Q%~u_3-?8j29YgLkFgsK1;#@Yj&lLMZLQg+^NJCA z`FGr&cAS+j`rWz2ULn7iv1LWi)@Krj2Xpv**gCR@+#;x*2H{p(bTQE6ewhn>7J-Xy z9hDbNAeFa&wadzg;uj!q-7!$)$A*G@GlX&CSl-n|UODK2`gq|A&3S6E2MH3_jZQB{ z$lF1i{z&jCAmFXCXmJy4F@K#mm@1&p^Qf#C#mIXUS;04M{H6G3t=Pi}O$vSCy30+H zv%!daXs&d@-62Nop_QXr)wWz5i>u2=?exZKS9Fmzx5on2W;tQbH6g@2%8)YYj89tf zsz9~52Crun7`GO^JY-99(f;bAUkbf|;tMS?>Y z0!w5m%V@uxXK$KAg&rrhiy(Q7Hl}ZQdN0Eh6N50bCc-OU`vR?-jP@2Qe zvTzkdcM~{#ZmaI_=PXJ?n@&R}K|!5DwL*Fu!UrTAD<+jPO=V1$<37*s`G^br zRdGE0O<7+$WJc~jdlE=bMns!UuDbdV_PU6JYQO<6PEUL&&5}azt)T!SL-bi=HR$M! zt>AJQ!S?*htarId3s4d*&Ob_liYO6By(#B^&wd7CCScOsVc%{@8LRkUhpH_M(A6~? z_na3n7D=0b6z149<82nrJnIv2KF|rt_xEYGFFq1|%Xr=CNVYob=J>IWtS8%yLoi*?a#>&K){f)Pj*I;XOh) zS&QEp`lX?~3KPtud{(b=8btD@qvvB!{9BvrP8sI>(~U_--{Z}l(|**9pD)iId>-BD zUbTOWJw?hR6v$0U;ZHa|=Sj@d7c2~UvogPu!U>4(kac0nx_oov?Z8PjLSJwzQuNHF z5-fH42zC1esu}XEeRd!8Fb@?K-Vh?ev_gofdEr&PJyPN%hR|Q-lA9o?Q4(w(bBRu{ zOEfplYj8ZF;hz>?Y(S>OKIaZj$PdCm2_li^MFcCbMg6%I<3xx8^!@CUB+G1w_e(cc zl*`)~H|43qE_>8kaHlnK#=_B<6%Z*p*Lcn9)-uPnY+|eu0EDRiw(+tcmc{`=Qhy%U zeE_BrC0i~@P0#g6ljwNJW`RABHmT{b5QFR@qctJ49Kq|3xn$O{V#V+4T_jrhW4OF= z3c`}&_F58btW;`)LqxQU{BbP&MHG=xQ=GZA7v)%CsFLAn&*Z%Hx94AFX4~or)i=|W z2sr$JiD%3Dd3ZIRQwLRe9rytj)d;HkzQQyO$7K)|VcB)f-xunUel) zO%Jb&;D@WZhz@nS@9yl;BVgW~JyFoSa)1yk>FWE_zD_XU!DH0w+|tDF6DDTCmX`wpt|i&V^&4 z!K>vQD;Of}TOZEZycd z36=zHqk}@Ku$)@4o}u{=pa=od_f&mE)$p2FLf@Rrlp&5)AHVV1z7pvp)%$ecQLD3i zeC2nhyZ^xIt z*ftI{HT6p~c8`(8lOJPQ5OiO?DV{qiC|RfWQA%EDa5xO?UCGLqa>`HrL0)>~y-Y|@ zi1Ovz0qAPGe5>~97b)aAG5BXTud!V!&jvnvSmokjuQq9J1ni)cf^1Me2iDIy?M+0L zVViM}veyXKS;vN1>PLkO--w-j+8W|#SZ^qEey1o1dlN!ml^LJf`P)r zeASY4M+opDlJ8Io4k0Vl{6ivtjGYf|D;Knhg%qUbeTa}M5XzOWJ;${dKBJeFn1|w( z7-u>WZO>BlwqRXn(yYd(jnLoY!#kz1ef!mQ8FH@p*MH7{HtbPKu_ef+a)CWGRXD9| z{y?r*AlZ9_&D!CB79pAfkF_eqAlDrLQ2LR{rCb@gE{ADoCF+BOkKhl#z=3kC!}EXQ z5A)0aL&QavIs(UYB!@G1j}`E%`zarkrHMR(y*X%Ha|%~j1U<>h;vt(2DhYmSV-;Sz|+@kfV+W31&?x;${=Cc z)j-72fCArgx;UV?K63UDDOXM*v7ML@Q$3qj6*pWC*30DAA)oQ7h3bOX>&-_HeZds@g^~lAC)$ z5`zUE0#I`%MIOr!JU47^jmzX;C4UVo)~i+`CpsOWz{`rl7{;GAyTkhi2FhWB?6A?n z*^YB9t|EaiUDAfJOE=KB-!G$bB?CT7r|{3Z+q<|pcmcl3a=Dj_NXN2adMv*nTi$Mg zl{B}=B)kx3EcLG)Oj-K(a{Z^R+oUTd_uNA4NB9Co`|7X4 zO(rgaX)#YplFvwI_=)iGL5inuA0v#_<{4sL0-#DP(VEmYjLW!b?EZxC=Q)7}OM1Iy z>kYi&`Bz}UZQzK;uPDo22las#;g#%F1DC(eXRYQA;~$#DkxHJlA|#E><% z1k3E?BoQcC*a#P0k<0w_!g!oMR>AC{JtjM9-|E`0v<}R{yFwr8`pup3#6x|jA-x&CP0kQ!Qe1@j^DnZKkd~1xZiplTpCp98 zjV#Ie=H1j6Jm$=gIu_0pkfq6bE|=N*=SZT2_pQS5DKf<4s# zQH0bOwX$Z6LI?ZM;l|Fbt44?YdFBZ{f||`FMp*&YFs(mdQ>F0}w1YK+^mWmkMz> zo+Ajn^3?u5VVwY&^nR7lT^RG4HMJOt;KKK>7`Imf`^@&or<%tSzCG7(Wg;wzI3$No zz2mW|lm@HOyA{%e4TaLE20uZel#VVR`B(`)0G`LObSN^;AUczd3JC}05+G8u@nfy$ z%$Ntfxp+ol0m{F+c>%LHL%m!9!!+N)TPkY_#9Hx5UXze`ila3D^7MJJz1TM(0{@}G{@@8RS{1qvg-iWHoH1-~^1 z2m!o2lfu=D!J~>S#xkC z_v>gZuId}eY?Bm}Xd~4^L-C;Yh8xTfl{-AzbJlQm%V~B|I|2zc-=KIw$-h_+%EPyB z$2Gf0pQmn(Zp9j!B#s0u_^Uhj`_0V&^y1;7^-j$PmEA+#$E%8gf}wbWX-m(HuJ-D<_fz6ecHx;NByLMC zvxMHb#Wko+4a7D}0SHbZrpeAA-xRvh`=|PVfbB%S+FJ

IimLcRvt`fS)~!++cL5 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 Ob5;MwrNRq$AO9adXap$$ diff --git a/connect/connect-datadog-logs-sink/dd_logs.png b/connect/connect-datadog-logs-sink/dd_logs.png index 28913f54b5c1c5858f7e16e6bdf413c8500d8be6..5494685e7240facc49f91a510f939de69214a028 100644 GIT binary patch literal 156553 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
IHzw+N$qSE}1`$fcJ;@=$ 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

tE`9O4KEVOwY*_0)kByBz$ZNdQqR>ps^5A;g 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

m?IcSkw;@CmHWS;_Q!}Yo?>>K8f3qt`u*|! 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�eE@DtQ&zx3t1|t)`oI0R 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

Mx9>`B7B7vI84Q9A2YO})oj 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 diff --git a/images/icons/opensearch.png b/images/icons/opensearch.png index b93a7c87d04cffcd24beef4410a40a5219ee583b..9794ac3703ac26df2e1d91ae81b59b8dbf6fc2b5 100644 GIT binary patch delta 3014 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 IM6N<$f(dro&Hw-a delta 3108 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 Date: Thu, 13 Mar 2025 11:01:33 +0100 Subject: [PATCH 294/659] =?UTF-8?q?=F0=9F=91=BE=20Handle=20AWS=5FPROFILE?= =?UTF-8?q?=20in=20AWS=20examples=20#6372?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 52 +++++++++++++-------------- scripts/cli/src/lib/utils_function.sh | 52 +++++++++++++-------------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index fd0938593d..876b77e662 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -9002,30 +9002,17 @@ function remove_partition() { } function aws() { - - if [ -z "$AWS_ACCESS_KEY_ID" ] && [ -z "$AWS_SECRET_ACCESS_KEY" ] && [ ! -f $HOME/.aws/credentials ] - then - logerror 'ERROR: Neither AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY or $HOME/.aws/credentials are set. AWS credentials must be set !' - if [ -z "$AWS_ACCESS_KEY_ID" ] - then - log 'AWS_ACCESS_KEY_ID environment variable is not set.' - fi - if [ -z "$AWS_SECRET_ACCESS_KEY" ] - then - log 'AWS_SECRET_ACCESS_KEY environment variable is not set.' - fi - if [ ! -f $HOME/.aws/credentials ] - then - log '$HOME/.aws/credentials does not exist.' - fi - return 1 - fi - if [ ! -z "$AWS_REGION" ] then if [ ! -f $HOME/.aws/config ] then aws_tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) + if [ -z "$PG_VERBOSE_MODE" ] + then + trap 'rm -rf $aws_tmp_dir' EXIT + else + log "🐛📂 not deleting aws tmp dir $aws_tmp_dir" + fi cat << EOF > $aws_tmp_dir/config [default] region = $AWS_REGION @@ -9041,15 +9028,14 @@ EOF # log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" if [ -f $aws_tmp_dir/config ] then - docker run --quiet --rm -iv $aws_tmp_dir/config:/root/.aws/config -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN -v $(pwd):/aws -v /tmp:/tmp amazon/aws-cli "$@" - rm -rf $aws_tmp_dir + docker run --quiet --rm -iv $aws_tmp_dir/config:/root/.aws/config -e AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID" -e AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY" -e AWS_SESSION_TOKEN="$AWS_SESSION_TOKEN" -v $(pwd):/aws -v /tmp:/tmp amazon/aws-cli "$@" else - docker run --quiet --rm -iv $HOME/.aws/config:/root/.aws/config -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN -v $(pwd):/aws -v /tmp:/tmp amazon/aws-cli "$@" + docker run --quiet --rm -iv $HOME/.aws/config:/root/.aws/config -e AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID" -e AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY" -e AWS_SESSION_TOKEN="$AWS_SESSION_TOKEN" -v $(pwd):/aws -v /tmp:/tmp amazon/aws-cli "$@" fi else if [ ! -f $HOME/.aws/credentials ] then - logerror '$HOME/.aws/credentials does not exist.' + logerror "❌ $HOME/.aws/credentials does not exist" else # log "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" docker run --quiet --rm -iv $HOME/.aws:/root/.aws -v $(pwd):/aws -v /tmp:/tmp amazon/aws-cli "$@" @@ -12573,12 +12559,12 @@ function login_and_maybe_set_azure_subscription () { function handle_aws_credentials () { export AWS_CREDENTIALS_FILE_NAME="/tmp/aws_credentials" - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ -z $AWS_SESSION_TOKEN ] + if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ -z "$AWS_SESSION_TOKEN" ] then if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) then - logerror "❌ either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 + logerror "❌ either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" + exit 1 else if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] then @@ -12611,6 +12597,14 @@ EOF fi fi else + if [ ! -z $AWS_PROFILE ] && [ -z "$AWS_SESSION_TOKEN" ] + then + logwarn "💭 AWS_PROFILE environment variable is set with $AWS_PROFILE" + logwarn "🚀 run manually this command and re-run the example again:" + echo "source <(aws configure export-credentials --profile $AWS_PROFILE --format env)" + exit 1 + fi + # # AWS short live credentials # @@ -12674,6 +12668,12 @@ EOF log "✨ Using AWS short live with credentials file $AWS_CREDENTIALS_FILE_NAME" export AWS_SHORT_LIVE_CREDENTIALS_USED=1 + else + if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) + then + logerror "❌ either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" + exit 1 + fi fi fi diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index b9349861c7..95cf0f0555 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -666,30 +666,17 @@ function remove_partition() { } function aws() { - - if [ -z "$AWS_ACCESS_KEY_ID" ] && [ -z "$AWS_SECRET_ACCESS_KEY" ] && [ ! -f $HOME/.aws/credentials ] - then - logerror 'ERROR: Neither AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY or $HOME/.aws/credentials are set. AWS credentials must be set !' - if [ -z "$AWS_ACCESS_KEY_ID" ] - then - log 'AWS_ACCESS_KEY_ID environment variable is not set.' - fi - if [ -z "$AWS_SECRET_ACCESS_KEY" ] - then - log 'AWS_SECRET_ACCESS_KEY environment variable is not set.' - fi - if [ ! -f $HOME/.aws/credentials ] - then - log '$HOME/.aws/credentials does not exist.' - fi - return 1 - fi - if [ ! -z "$AWS_REGION" ] then if [ ! -f $HOME/.aws/config ] then aws_tmp_dir=$(mktemp -d -t pg-XXXXXXXXXX) + if [ -z "$PG_VERBOSE_MODE" ] + then + trap 'rm -rf $aws_tmp_dir' EXIT + else + log "🐛📂 not deleting aws tmp dir $aws_tmp_dir" + fi cat << EOF > $aws_tmp_dir/config [default] region = $AWS_REGION @@ -705,15 +692,14 @@ EOF # log "💭 Using environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY" if [ -f $aws_tmp_dir/config ] then - docker run --quiet --rm -iv $aws_tmp_dir/config:/root/.aws/config -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN -v $(pwd):/aws -v /tmp:/tmp amazon/aws-cli "$@" - rm -rf $aws_tmp_dir + docker run --quiet --rm -iv $aws_tmp_dir/config:/root/.aws/config -e AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID" -e AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY" -e AWS_SESSION_TOKEN="$AWS_SESSION_TOKEN" -v $(pwd):/aws -v /tmp:/tmp amazon/aws-cli "$@" else - docker run --quiet --rm -iv $HOME/.aws/config:/root/.aws/config -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN -v $(pwd):/aws -v /tmp:/tmp amazon/aws-cli "$@" + docker run --quiet --rm -iv $HOME/.aws/config:/root/.aws/config -e AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID" -e AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY" -e AWS_SESSION_TOKEN="$AWS_SESSION_TOKEN" -v $(pwd):/aws -v /tmp:/tmp amazon/aws-cli "$@" fi else if [ ! -f $HOME/.aws/credentials ] then - logerror '$HOME/.aws/credentials does not exist.' + logerror "❌ $HOME/.aws/credentials does not exist" else # log "💭 AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set based on $HOME/.aws/credentials" docker run --quiet --rm -iv $HOME/.aws:/root/.aws -v $(pwd):/aws -v /tmp:/tmp amazon/aws-cli "$@" @@ -4304,12 +4290,12 @@ function login_and_maybe_set_azure_subscription () { function handle_aws_credentials () { export AWS_CREDENTIALS_FILE_NAME="/tmp/aws_credentials" - if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ -z $AWS_SESSION_TOKEN ] + if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] && [ -z "$AWS_SESSION_TOKEN" ] then if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) then - logerror "❌ either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" - exit 1 + logerror "❌ either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" + exit 1 else if [ ! -z "$AWS_ACCESS_KEY_ID" ] && [ ! -z "$AWS_SECRET_ACCESS_KEY" ] then @@ -4341,6 +4327,14 @@ EOF fi fi else + if [ ! -z $AWS_PROFILE ] && [ -z "$AWS_SESSION_TOKEN" ] + then + logwarn "💭 AWS_PROFILE environment variable is set with $AWS_PROFILE" + logwarn "🚀 run manually this command and re-run the example again:" + echo "source <(aws configure export-credentials --profile $AWS_PROFILE --format env)" + exit 1 + fi + # # AWS short live credentials # @@ -4404,6 +4398,12 @@ EOF log "✨ Using AWS short live with credentials file $AWS_CREDENTIALS_FILE_NAME" export AWS_SHORT_LIVE_CREDENTIALS_USED=1 + else + if [ ! -f $HOME/.aws/credentials ] && ( [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ] ) + then + logerror "❌ either the file $HOME/.aws/credentials is not present or environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are not set!" + exit 1 + fi fi fi From 905230195cbf8a25e18aa921532b8ce47933106d Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 14 Mar 2025 11:32:13 +0100 Subject: [PATCH 295/659] 8 days ago --- connect/connect-marketo-source/marketo-source.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connect/connect-marketo-source/marketo-source.sh b/connect/connect-marketo-source/marketo-source.sh index 9473e07260..586ca31f57 100755 --- a/connect/connect-marketo-source/marketo-source.sh +++ b/connect/connect-marketo-source/marketo-source.sh @@ -65,9 +65,9 @@ done if [[ "$OSTYPE" == "darwin"* ]] then - SINCE=$(date -v-8H +%Y-%m-%dT%H:%M:%SZ) + SINCE=$(date -v-8d +%Y-%m-%dT%H:%M:%SZ) else - SINCE=$(date -d '8 hour ago' +%Y-%m-%dT%H:%M:%SZ) + SINCE=$(date -d '8 days ago' +%Y-%m-%dT%H:%M:%SZ) fi # playground debug log-level set --package "org.apache.http" --level TRACE From cf8854680c5eecf2eb31e70757da95d85f1c084f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 14 Mar 2025 13:27:37 +0100 Subject: [PATCH 296/659] fix --- connect/connect-github-source/github-source.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connect/connect-github-source/github-source.sh b/connect/connect-github-source/github-source.sh index 719ec9070a..098c2a395a 100755 --- a/connect/connect-github-source/github-source.sh +++ b/connect/connect-github-source/github-source.sh @@ -45,7 +45,7 @@ else playground connector create-or-update --connector github-source << EOF { "connector.class": "io.confluent.connect.github.GithubSourceConnector", - "topic.name.pattern":"github-topic-${entityName}", + "topic.name.pattern":"github-topic-\${entityName}", "tasks.max": "1", "github.service.url":"https://api.github.com", "github.repositories":"apache/kafka", From 2218c933da0a6b78a4ac419283cf226db88243db Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 17 Mar 2025 10:41:06 +0100 Subject: [PATCH 297/659] no symlinks for gitignore --- scripts/cli/playground | 12 +++++++++++- scripts/cli/src/commands/repro/bootstrap.sh | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 876b77e662..864fb31eb7 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -17229,7 +17229,7 @@ playground_repro_bootstrap_command() { cat $repro_test_file | grep -v "#!/bin/bash" >> $tmp_dir/tmp_file mv $tmp_dir/tmp_file $repro_test_file - for file in README.md docker-compose*.yml keyfile.json stop.sh .gitignore sql-datagen + for file in README.md docker-compose*.yml keyfile.json stop.sh sql-datagen do if [ -f $file ] then @@ -17239,6 +17239,16 @@ playground_repro_bootstrap_command() { fi done + for file in .gitignore + do + if [ -f $file ] + then + cd $repro_dir > /dev/null + cp ../../$dir2/$file . + cd - > /dev/null + fi + done + if [ "$producer" != "none" ] then case "${producer}" in diff --git a/scripts/cli/src/commands/repro/bootstrap.sh b/scripts/cli/src/commands/repro/bootstrap.sh index 1417f28701..d5d67c94a3 100644 --- a/scripts/cli/src/commands/repro/bootstrap.sh +++ b/scripts/cli/src/commands/repro/bootstrap.sh @@ -378,7 +378,7 @@ cat $tmp_dir/intro > $tmp_dir/tmp_file cat $repro_test_file | grep -v "#!/bin/bash" >> $tmp_dir/tmp_file mv $tmp_dir/tmp_file $repro_test_file -for file in README.md docker-compose*.yml keyfile.json stop.sh .gitignore sql-datagen +for file in README.md docker-compose*.yml keyfile.json stop.sh sql-datagen do if [ -f $file ] then @@ -388,6 +388,16 @@ do fi done +for file in .gitignore +do + if [ -f $file ] + then + cd $repro_dir > /dev/null + cp ../../$dir2/$file . + cd - > /dev/null + fi +done + if [ "$producer" != "none" ] then case "${producer}" in From 889ac0216a512f6cafc9c9649b762cdde74c8e3f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 21 Mar 2025 09:36:24 +0100 Subject: [PATCH 298/659] new account naming from snow --- ccloud/fm-snowflake-sink/README.md | 4 ++-- connect/connect-snowflake-sink/README.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ccloud/fm-snowflake-sink/README.md b/ccloud/fm-snowflake-sink/README.md index ca2d3c3dbb..32609b6b6f 100644 --- a/ccloud/fm-snowflake-sink/README.md +++ b/ccloud/fm-snowflake-sink/README.md @@ -21,10 +21,10 @@ https://.snowflakecomputing.com Example: ``` -https://of77992.eu-west-2.aws.snowflakecomputing.com +https://MZLPQCM-DW39774.snowflakecomputing.com ``` -`SNOWFLAKE_ACCOUNT_NAME` should be set with `of77992.eu-west-2.aws` +`SNOWFLAKE_ACCOUNT_NAME` should be set with `MZLPQCM-DW39774` ## Prerequisites diff --git a/connect/connect-snowflake-sink/README.md b/connect/connect-snowflake-sink/README.md index ded9bb84e3..d6dcbebeba 100644 --- a/connect/connect-snowflake-sink/README.md +++ b/connect/connect-snowflake-sink/README.md @@ -25,10 +25,10 @@ https://.snowflakecomputing.com Example: ``` -https://of77992.eu-west-2.aws.snowflakecomputing.com +https://MZLPQCM-DW39774.snowflakecomputing.com ``` -`SNOWFLAKE_ACCOUNT_NAME` should be set with `of77992.eu-west-2.aws` +`SNOWFLAKE_ACCOUNT_NAME` should be set with `MZLPQCM-DW39774` ## How to run From 065a347e815009b43bfe1cd5d7179397320db1cc Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 21 Mar 2025 09:37:43 +0100 Subject: [PATCH 299/659] wip --- secrets.tar.gpg | Bin 7784 -> 7781 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/secrets.tar.gpg b/secrets.tar.gpg index af9e6ecc4ddf61ab77eafd6ef436bb8c456bacb8..4d707f813dad1d4ab96373c76f8bf871d97ec883 100644 GIT binary patch literal 7781 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 Date: Fri, 21 Mar 2025 10:34:44 +0100 Subject: [PATCH 300/659] wip --- scripts/cli/tag-list.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/cli/tag-list.txt b/scripts/cli/tag-list.txt index e3a3955ded..fa5f678350 100644 --- a/scripts/cli/tag-list.txt +++ b/scripts/cli/tag-list.txt @@ -125,6 +125,7 @@ 7.1.13 7.1.14 7.1.15 +7.1.16 7.1.2 7.1.3 7.1.4 @@ -139,6 +140,7 @@ 7.2.11 7.2.12 7.2.13 +7.2.14 7.2.2 7.2.3 7.2.4 @@ -151,6 +153,7 @@ 7.3.1 7.3.10 7.3.11 +7.3.12 7.3.2 7.3.3 7.3.4 @@ -176,6 +179,7 @@ 7.5.5 7.5.6 7.5.7 +7.5.8 7.6.0 7.6.1 7.6.2 From eef787d7d80467c10823c62bf69ba49b70a0e344 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 21 Mar 2025 10:35:00 +0100 Subject: [PATCH 301/659] =?UTF-8?q?wip=20for=20=F0=9F=94=90=20Create=20SQS?= =?UTF-8?q?=20AWS=20custom=20credentials=20example=20with=202.x=20#5174?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../awscredentialsprovider-v2/Dockerfile | 2 + .../awscredentialsprovider-v2/pom.xml | 103 ++++++++++++++ .../main/java/com/github/vdesabou/.gitignore | 0 .../AwsAssumeRoleCredentialsProvider.java | 126 ++++++++++++++++++ .../src/main/resources/log4j.properties | 5 + ...le-with-custom-aws-credential-provider.yml | 10 ++ ...le-with-custom-aws-credential-provider.yml | 8 -- ...ole-with-custom-aws-credential-provider.sh | 90 +++++++++++-- 8 files changed, 325 insertions(+), 19 deletions(-) create mode 100644 connect/connect-aws-sqs-source/awscredentialsprovider-v2/Dockerfile create mode 100644 connect/connect-aws-sqs-source/awscredentialsprovider-v2/pom.xml create mode 100644 connect/connect-aws-sqs-source/awscredentialsprovider-v2/src/main/java/com/github/vdesabou/.gitignore create mode 100644 connect/connect-aws-sqs-source/awscredentialsprovider-v2/src/main/java/com/github/vdesabou/AwsAssumeRoleCredentialsProvider.java create mode 100644 connect/connect-aws-sqs-source/awscredentialsprovider-v2/src/main/resources/log4j.properties create mode 100644 connect/connect-aws-sqs-source/docker-compose.plaintext.assuming-iam-role-with-custom-aws-credential-provider.yml delete mode 100644 connect/connect-aws-sqs-source/docker-compose.plaintext.backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.yml diff --git a/connect/connect-aws-sqs-source/awscredentialsprovider-v2/Dockerfile b/connect/connect-aws-sqs-source/awscredentialsprovider-v2/Dockerfile new file mode 100644 index 0000000000..bc6de3ae93 --- /dev/null +++ b/connect/connect-aws-sqs-source/awscredentialsprovider-v2/Dockerfile @@ -0,0 +1,2 @@ +FROM eclipse-temurin:11-jdk +CMD sleep infinity \ No newline at end of file diff --git a/connect/connect-aws-sqs-source/awscredentialsprovider-v2/pom.xml b/connect/connect-aws-sqs-source/awscredentialsprovider-v2/pom.xml new file mode 100644 index 0000000000..c5e37c0d18 --- /dev/null +++ b/connect/connect-aws-sqs-source/awscredentialsprovider-v2/pom.xml @@ -0,0 +1,103 @@ + + + 4.0.0 + com.github.vdesabou + awscredentialsprovider + 1.0.0 + jar + + 1.8 + 1.8 + UTF-8 + UTF-8 + 6.2.0 + 2.8.0 + 2.29.35 + + + + confluent + Confluent + https://packages.confluent.io/maven/ + + + + + org.apache.kafka + kafka-clients + ${kafka.client.tag} + + + + + + org.slf4j + slf4j-api + 1.7.25 + + + + + org.slf4j + slf4j-log4j12 + 1.7.25 + + + + software.amazon.awssdk + bom + ${aws.sdk.version} + pom + import + + + software.amazon.awssdk + sts + ${aws.sdk.version} + + + + + + install + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + 1.8 + 1.8 + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.2.0 + + + jar-with-dependencies + + + + true + com.github.vdesabou.AwsAssumeRoleCredentialsProvider + + + + + + assemble-all + package + + single + + + + + + + diff --git a/connect/connect-aws-sqs-source/awscredentialsprovider-v2/src/main/java/com/github/vdesabou/.gitignore b/connect/connect-aws-sqs-source/awscredentialsprovider-v2/src/main/java/com/github/vdesabou/.gitignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/connect/connect-aws-sqs-source/awscredentialsprovider-v2/src/main/java/com/github/vdesabou/AwsAssumeRoleCredentialsProvider.java b/connect/connect-aws-sqs-source/awscredentialsprovider-v2/src/main/java/com/github/vdesabou/AwsAssumeRoleCredentialsProvider.java new file mode 100644 index 0000000000..cce9ec56b1 --- /dev/null +++ b/connect/connect-aws-sqs-source/awscredentialsprovider-v2/src/main/java/com/github/vdesabou/AwsAssumeRoleCredentialsProvider.java @@ -0,0 +1,126 @@ +/* + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.github.vdesabou; + +import software.amazon.awssdk.auth.credentials.AwsCredentials; +import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; +//import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.services.sts.StsClient; +import software.amazon.awssdk.services.sts.auth.StsAssumeRoleCredentialsProvider; +import software.amazon.awssdk.services.sts.model.AssumeRoleRequest; + +import org.apache.kafka.common.Configurable; +import org.apache.kafka.common.config.AbstractConfig; +import org.apache.kafka.common.config.ConfigDef; +// import com.amazonaws.auth.BasicAWSCredentials; +import java.util.Map; +// import com.amazonaws.services.securitytoken.AWSSecurityTokenService; +// import com.amazonaws.auth.AWSStaticCredentialsProvider; +import org.apache.kafka.common.config.types.Password; + +/** + * AWS credentials provider that uses the AWS Security Token Service to assume a Role and create a + * temporary, short-lived session to use for authentication. This credentials provider does not + * support refreshing the credentials in a background thread. + */ +public class AwsAssumeRoleCredentialsProvider implements AwsCredentialsProvider, Configurable { + + public static final String ROLE_EXTERNAL_ID_CONFIG = "sts.role.external.id"; + public static final String ROLE_ARN_CONFIG = "sts.role.arn"; + public static final String ROLE_SESSION_NAME_CONFIG = "sts.role.session.name"; + + public static final String ACCESS_KEY_ID_CONFIG = "sts.aws.access.key.id"; + public static final String SECRET_KEY_ID_CONFIG = "sts.aws.secret.key.id"; + + private static final ConfigDef STS_CONFIG_DEF = new ConfigDef() + .define( + ROLE_EXTERNAL_ID_CONFIG, + ConfigDef.Type.STRING, + ConfigDef.Importance.MEDIUM, + "The role external ID used when retrieving session credentials under an assumed role." + ).define( + ROLE_ARN_CONFIG, + ConfigDef.Type.STRING, + ConfigDef.Importance.HIGH, + "Role ARN to use when starting a session." + ).define( + ROLE_SESSION_NAME_CONFIG, + ConfigDef.Type.STRING, + ConfigDef.Importance.HIGH, + "Role session name to use when starting a session" + ).define( + ACCESS_KEY_ID_CONFIG, + ConfigDef.Type.STRING, + ConfigDef.Importance.HIGH, + "The AWS access key that will be used" + ).define( + SECRET_KEY_ID_CONFIG, + ConfigDef.Type.PASSWORD, + ConfigDef.Importance.HIGH, + "The AWS access key that will be used" + ); + + private String roleArn; + private String roleExternalId; + private String roleSessionName; + // private BasicAWSCredentials basicCredentials; + + // STSAssumeRoleCredentialsProvider takes care of refreshing short-lived + // credentials 60 seconds before it's expiry + private static StsAssumeRoleCredentialsProvider stsCredentialProvider; + + @Override + public void configure(Map configs) { + AbstractConfig config = new AbstractConfig(STS_CONFIG_DEF, configs); + roleArn = config.getString(ROLE_ARN_CONFIG); + roleExternalId = config.getString(ROLE_EXTERNAL_ID_CONFIG); + roleSessionName = config.getString(ROLE_SESSION_NAME_CONFIG); + final String accessKeyId = (String) configs.get(ACCESS_KEY_ID_CONFIG); + final String secretKey = (String) configs.get(SECRET_KEY_ID_CONFIG); + if (!accessKeyId.equals("") && !secretKey.equals("")) { + // + } else { + // basicCredentials = null; + // stsCredentialProvider = new STSAssumeRoleSessionCredentialsProvider.Builder(roleArn, roleSessionName) + // // default sts client will internally use default credentials chain provider + // // https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html#credentials-default + // .withStsClient(AWSSecurityTokenServiceClientBuilder.defaultClient()) + // .withExternalId(roleExternalId) + // .build(); + + stsCredentialProvider = StsAssumeRoleCredentialsProvider + .builder() + // .asyncCredentialUpdateEnabled(true) + .stsClient(StsClient.create()) + .refreshRequest(() -> AssumeRoleRequest + .builder() + .roleArn(roleArn) + .roleSessionName(roleSessionName) + .build()) + // .withExternalId(roleExternalId) + .build(); + } + } + + public static AwsCredentialsProvider create() { + return stsCredentialProvider; + } + + @Override + public AwsCredentials resolveCredentials() { + return stsCredentialProvider.resolveCredentials(); + } +} diff --git a/connect/connect-aws-sqs-source/awscredentialsprovider-v2/src/main/resources/log4j.properties b/connect/connect-aws-sqs-source/awscredentialsprovider-v2/src/main/resources/log4j.properties new file mode 100644 index 0000000000..607f23f6c2 --- /dev/null +++ b/connect/connect-aws-sqs-source/awscredentialsprovider-v2/src/main/resources/log4j.properties @@ -0,0 +1,5 @@ +log4j.rootLogger=INFO, stdout, kafkaAppender + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=[%d] %p %m (%c)%n \ No newline at end of file diff --git a/connect/connect-aws-sqs-source/docker-compose.plaintext.assuming-iam-role-with-custom-aws-credential-provider.yml b/connect/connect-aws-sqs-source/docker-compose.plaintext.assuming-iam-role-with-custom-aws-credential-provider.yml new file mode 100644 index 0000000000..453c11fc03 --- /dev/null +++ b/connect/connect-aws-sqs-source/docker-compose.plaintext.assuming-iam-role-with-custom-aws-credential-provider.yml @@ -0,0 +1,10 @@ +--- +services: + connect: + volumes: + - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials + - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config + - ../../connect/connect-aws-sqs-source/$COMPONENT_NAME/target/awscredentialsprovider-1.0.0-jar-with-dependencies.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-sqs/lib/awscredentialsprovider-1.0.0-jar-with-dependencies.jar + environment: + CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-sqs + AWS_REGION: $AWS_REGION \ No newline at end of file diff --git a/connect/connect-aws-sqs-source/docker-compose.plaintext.backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.yml b/connect/connect-aws-sqs-source/docker-compose.plaintext.backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.yml deleted file mode 100644 index 63d3b15563..0000000000 --- a/connect/connect-aws-sqs-source/docker-compose.plaintext.backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -services: - connect: - volumes: - - ../../connect/connect-aws-sqs-source/awscredentialsprovider/target/awscredentialsprovider-1.0.0-jar-with-dependencies.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-sqs/lib/awscredentialsprovider-1.0.0-jar-with-dependencies.jar - environment: - CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-sqs - AWS_REGION: $AWS_REGION \ No newline at end of file diff --git a/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh b/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh index 7892ea7ad9..e07bc47fdb 100755 --- a/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh +++ b/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh @@ -6,14 +6,10 @@ source ${DIR}/../../scripts/utils.sh logwarn "⚠️ This example and associated custom code is not supported, use at your own risks !" +export COMPONENT_NAME="awscredentialsprovider" if version_gt $CONNECTOR_TAG "1.9.9" then - logwarn "WARN: connector version >= 2.0.0 do not support this custom credentials provider as it was build with AWS JDK 1.x" - # 08:54:15 🔥 Command failed with error code 400 - # 08:54:15 🔥 Connector configuration is invalid and contains the following 1 error(s): - # Invalid value class com.github.vdesabou.AwsAssumeRoleCredentialsProvider for configuration sqs.credentials.provider.class: Class must extend: interface software.amazon.awssdk.auth.credentials.AwsCredentialsProvider - # You can also find the above list of errors at the endpoint `/connector-plugins/{connectorType}/config/validate` - exit 111 + export COMPONENT_NAME="awscredentialsprovider-v2" fi AWS_STS_ROLE_ARN=${AWS_STS_ROLE_ARN:-$1} @@ -38,7 +34,7 @@ fi handle_aws_credentials -for component in awscredentialsprovider +for component in $COMPONENT_NAME do set +e log "🏗 Building jar for ${component}" @@ -53,7 +49,7 @@ do done PLAYGROUND_ENVIRONMENT=${PLAYGROUND_ENVIRONMENT:-"plaintext"} -playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.backup-and-restore-assuming-iam-role-with-custom-aws-credential-provider.yml" +playground start-environment --environment "${PLAYGROUND_ENVIRONMENT}" --docker-compose-override-file "${PWD}/docker-compose.plaintext.assuming-iam-role-with-custom-aws-credential-provider.yml" QUEUE_NAME=pg${USER}sqs${TAG} QUEUE_NAME=${QUEUE_NAME//[-._]/} @@ -103,8 +99,8 @@ playground connector create-or-update --connector sqs-source << EOF "sqs.credentials.provider.sts.role.arn": "$AWS_STS_ROLE_ARN", "sqs.credentials.provider.sts.role.session.name": "session-name", "sqs.credentials.provider.sts.role.external.id": "123", - "sqs.credentials.provider.sts.aws.access.key.id": "$AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID", - "sqs.credentials.provider.sts.aws.secret.key.id": "$AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY", + "_sqs.credentials.provider.sts.aws.access.key.id": "$AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID", + "_sqs.credentials.provider.sts.aws.secret.key.id": "$AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY", "confluent.license": "", "confluent.topic.bootstrap.servers": "broker:9092", "confluent.topic.replication.factor": "1", @@ -115,4 +111,76 @@ playground connector create-or-update --connector sqs-source << EOF EOF log "Verify we have received the data in test-sqs-source topic" -playground topic consume --topic test-sqs-source --min-expected-messages 2 --timeout 60 \ No newline at end of file +playground topic consume --topic test-sqs-source --min-expected-messages 2 --timeout 60 + + +# [2025-03-21 09:11:30,583] WARN /connectors/sqs-source/config (org.eclipse.jetty.server.HttpChannel:776) +# javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: java.lang.IllegalAccessError: class software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder tried to access private field software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.overrideConfig (software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder and software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder are in unnamed module of loader org.apache.kafka.connect.runtime.isolation.PluginClassLoader @5f7b97da) +# at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:410) +# at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346) +# at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:358) +# at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:311) +# at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205) +# at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) +# at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:554) +# at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) +# at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) +# at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) +# at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440) +# at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) +# at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505) +# at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) +# at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) +# at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355) +# at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) +# at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:234) +# at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:181) +# at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) +# at org.eclipse.jetty.server.Server.handle(Server.java:516) +# at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487) +# at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732) +# at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479) +# at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) +# at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) +# at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) +# at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) +# at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338) +# at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315) +# at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173) +# at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) +# at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409) +# at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) +# at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) +# at java.base/java.lang.Thread.run(Unknown Source) +# Caused by: org.glassfish.jersey.server.ContainerException: java.lang.IllegalAccessError: class software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder tried to access private field software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.overrideConfig (software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder and software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder are in unnamed module of loader org.apache.kafka.connect.runtime.isolation.PluginClassLoader @5f7b97da) +# at org.glassfish.jersey.servlet.internal.ResponseWriter.rethrow(ResponseWriter.java:255) +# at org.glassfish.jersey.servlet.internal.ResponseWriter.failure(ResponseWriter.java:237) +# at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:438) +# at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:263) +# at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) +# at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244) +# at org.glassfish.jersey.internal.Errors.process(Errors.java:292) +# at org.glassfish.jersey.internal.Errors.process(Errors.java:274) +# at org.glassfish.jersey.internal.Errors.process(Errors.java:244) +# at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265) +# at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:234) +# at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684) +# at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394) +# ... 35 more +# Caused by: java.lang.IllegalAccessError: class software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder tried to access private field software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.overrideConfig (software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder and software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder are in unnamed module of loader org.apache.kafka.connect.runtime.isolation.PluginClassLoader @5f7b97da) +# at software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder.setOverrides(AwsDefaultClientBuilder.java:205) +# at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.asyncClientConfiguration(SdkDefaultClientBuilder.java:212) +# at software.amazon.awssdk.services.sqs.DefaultSqsAsyncClientBuilder.buildClient(DefaultSqsAsyncClientBuilder.java:37) +# at software.amazon.awssdk.services.sqs.DefaultSqsAsyncClientBuilder.buildClient(DefaultSqsAsyncClientBuilder.java:25) +# at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.build(SdkDefaultClientBuilder.java:155) +# at io.confluent.connect.sqs.util.SqsClientUtil.createAsyncClient(SqsClientUtil.java:46) +# at io.confluent.connect.sqs.source.SqsSourceConfigValidation.performValidation(SqsSourceConfigValidation.java:89) +# at io.confluent.connect.utils.validators.all.ConfigValidation.validate(ConfigValidation.java:185) +# at io.confluent.connect.sqs.source.SqsSourceConnector.validate(SqsSourceConnector.java:80) +# at org.apache.kafka.connect.runtime.AbstractHerder.validateConnectorConfig(AbstractHerder.java:745) +# at org.apache.kafka.connect.runtime.AbstractHerder.lambda$validateConnectorConfig$5(AbstractHerder.java:597) +# at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) +# at java.base/java.util.concurrent.FutureTask.run(Unknown Source) +# at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) +# at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) +# ... 1 more \ No newline at end of file From ddc2075744a6ab6f37d415e194bcb506c1fdde42 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 21 Mar 2025 12:19:35 +0100 Subject: [PATCH 302/659] =?UTF-8?q?=F0=9F=94=90=20Create=20SQS=20AWS=20cus?= =?UTF-8?q?tom=20credentials=20example=20with=202.x=20#5174?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AwsAssumeRoleCredentialsProvider.java | 104 ++++-------------- ...le-with-custom-aws-credential-provider.yml | 10 +- ...ole-with-custom-aws-credential-provider.sh | 79 +------------ 3 files changed, 30 insertions(+), 163 deletions(-) diff --git a/connect/connect-aws-sqs-source/awscredentialsprovider-v2/src/main/java/com/github/vdesabou/AwsAssumeRoleCredentialsProvider.java b/connect/connect-aws-sqs-source/awscredentialsprovider-v2/src/main/java/com/github/vdesabou/AwsAssumeRoleCredentialsProvider.java index cce9ec56b1..a58f6b4736 100644 --- a/connect/connect-aws-sqs-source/awscredentialsprovider-v2/src/main/java/com/github/vdesabou/AwsAssumeRoleCredentialsProvider.java +++ b/connect/connect-aws-sqs-source/awscredentialsprovider-v2/src/main/java/com/github/vdesabou/AwsAssumeRoleCredentialsProvider.java @@ -15,112 +15,46 @@ package com.github.vdesabou; +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.AwsCredentials; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -//import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; import software.amazon.awssdk.services.sts.StsClient; import software.amazon.awssdk.services.sts.auth.StsAssumeRoleCredentialsProvider; import software.amazon.awssdk.services.sts.model.AssumeRoleRequest; -import org.apache.kafka.common.Configurable; -import org.apache.kafka.common.config.AbstractConfig; -import org.apache.kafka.common.config.ConfigDef; -// import com.amazonaws.auth.BasicAWSCredentials; -import java.util.Map; -// import com.amazonaws.services.securitytoken.AWSSecurityTokenService; -// import com.amazonaws.auth.AWSStaticCredentialsProvider; -import org.apache.kafka.common.config.types.Password; - -/** - * AWS credentials provider that uses the AWS Security Token Service to assume a Role and create a - * temporary, short-lived session to use for authentication. This credentials provider does not - * support refreshing the credentials in a background thread. - */ -public class AwsAssumeRoleCredentialsProvider implements AwsCredentialsProvider, Configurable { - - public static final String ROLE_EXTERNAL_ID_CONFIG = "sts.role.external.id"; - public static final String ROLE_ARN_CONFIG = "sts.role.arn"; - public static final String ROLE_SESSION_NAME_CONFIG = "sts.role.session.name"; - - public static final String ACCESS_KEY_ID_CONFIG = "sts.aws.access.key.id"; - public static final String SECRET_KEY_ID_CONFIG = "sts.aws.secret.key.id"; - - private static final ConfigDef STS_CONFIG_DEF = new ConfigDef() - .define( - ROLE_EXTERNAL_ID_CONFIG, - ConfigDef.Type.STRING, - ConfigDef.Importance.MEDIUM, - "The role external ID used when retrieving session credentials under an assumed role." - ).define( - ROLE_ARN_CONFIG, - ConfigDef.Type.STRING, - ConfigDef.Importance.HIGH, - "Role ARN to use when starting a session." - ).define( - ROLE_SESSION_NAME_CONFIG, - ConfigDef.Type.STRING, - ConfigDef.Importance.HIGH, - "Role session name to use when starting a session" - ).define( - ACCESS_KEY_ID_CONFIG, - ConfigDef.Type.STRING, - ConfigDef.Importance.HIGH, - "The AWS access key that will be used" - ).define( - SECRET_KEY_ID_CONFIG, - ConfigDef.Type.PASSWORD, - ConfigDef.Importance.HIGH, - "The AWS access key that will be used" - ); +public class AwsAssumeRoleCredentialsProvider implements AwsCredentialsProvider { private String roleArn; private String roleExternalId; private String roleSessionName; - // private BasicAWSCredentials basicCredentials; - // STSAssumeRoleCredentialsProvider takes care of refreshing short-lived - // credentials 60 seconds before it's expiry private static StsAssumeRoleCredentialsProvider stsCredentialProvider; - @Override - public void configure(Map configs) { - AbstractConfig config = new AbstractConfig(STS_CONFIG_DEF, configs); - roleArn = config.getString(ROLE_ARN_CONFIG); - roleExternalId = config.getString(ROLE_EXTERNAL_ID_CONFIG); - roleSessionName = config.getString(ROLE_SESSION_NAME_CONFIG); - final String accessKeyId = (String) configs.get(ACCESS_KEY_ID_CONFIG); - final String secretKey = (String) configs.get(SECRET_KEY_ID_CONFIG); - if (!accessKeyId.equals("") && !secretKey.equals("")) { - // - } else { - // basicCredentials = null; - // stsCredentialProvider = new STSAssumeRoleSessionCredentialsProvider.Builder(roleArn, roleSessionName) - // // default sts client will internally use default credentials chain provider - // // https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html#credentials-default - // .withStsClient(AWSSecurityTokenServiceClientBuilder.defaultClient()) - // .withExternalId(roleExternalId) - // .build(); - - stsCredentialProvider = StsAssumeRoleCredentialsProvider + public static AwsCredentialsProvider create() { + String accessKeyId = System.getenv("AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID"); + String secretKey = System.getenv("AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY"); + String roleArn = System.getenv("AWS_STS_ROLE_ARN"); + String roleSessionName = System.getenv("AWS_STS_SESSION_NAME"); + String roleExternalId = System.getenv("AWS_STS_EXTERNAL_ID"); + + AwsBasicCredentials basicCredentials = AwsBasicCredentials.create(accessKeyId, secretKey); + + return StsAssumeRoleCredentialsProvider .builder() - // .asyncCredentialUpdateEnabled(true) - .stsClient(StsClient.create()) - .refreshRequest(() -> AssumeRoleRequest - .builder() + .stsClient(StsClient.builder() + .credentialsProvider(StaticCredentialsProvider.create(basicCredentials)) + .build()) + .refreshRequest(() -> AssumeRoleRequest.builder() .roleArn(roleArn) .roleSessionName(roleSessionName) + .externalId(roleExternalId) .build()) - // .withExternalId(roleExternalId) .build(); - } } - public static AwsCredentialsProvider create() { - return stsCredentialProvider; - } - @Override public AwsCredentials resolveCredentials() { return stsCredentialProvider.resolveCredentials(); } -} +} \ No newline at end of file diff --git a/connect/connect-aws-sqs-source/docker-compose.plaintext.assuming-iam-role-with-custom-aws-credential-provider.yml b/connect/connect-aws-sqs-source/docker-compose.plaintext.assuming-iam-role-with-custom-aws-credential-provider.yml index 453c11fc03..b0d5730da0 100644 --- a/connect/connect-aws-sqs-source/docker-compose.plaintext.assuming-iam-role-with-custom-aws-credential-provider.yml +++ b/connect/connect-aws-sqs-source/docker-compose.plaintext.assuming-iam-role-with-custom-aws-credential-provider.yml @@ -2,9 +2,13 @@ services: connect: volumes: - - ${AWS_CREDENTIALS_FILE_NAME:-/dev/null}:$CONNECT_CONTAINER_HOME_DIR/.aws/credentials - - $HOME/.aws/config:$CONNECT_CONTAINER_HOME_DIR/.aws/config - ../../connect/connect-aws-sqs-source/$COMPONENT_NAME/target/awscredentialsprovider-1.0.0-jar-with-dependencies.jar:/usr/share/confluent-hub-components/confluentinc-kafka-connect-sqs/lib/awscredentialsprovider-1.0.0-jar-with-dependencies.jar environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-sqs - AWS_REGION: $AWS_REGION \ No newline at end of file + AWS_REGION: $AWS_REGION + # with v2 conector config is not working, need to use env variables + AWS_STS_ROLE_ARN: $AWS_STS_ROLE_ARN + AWS_STS_SESSION_NAME: "session-name" + AWS_STS_EXTERNAL_ID: "123" + AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID: $AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID + AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY: $AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY \ No newline at end of file diff --git a/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh b/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh index e07bc47fdb..09848128fe 100755 --- a/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh +++ b/connect/connect-aws-sqs-source/sqs-source-assuming-iam-role-with-custom-aws-credential-provider.sh @@ -96,11 +96,12 @@ playground connector create-or-update --connector sqs-source << EOF "kafka.topic": "test-sqs-source", "sqs.url": "$QUEUE_URL", "sqs.credentials.provider.class": "com.github.vdesabou.AwsAssumeRoleCredentialsProvider", + "_comment": "The following sts parameters are not used when using v2 of the connector", "sqs.credentials.provider.sts.role.arn": "$AWS_STS_ROLE_ARN", "sqs.credentials.provider.sts.role.session.name": "session-name", "sqs.credentials.provider.sts.role.external.id": "123", - "_sqs.credentials.provider.sts.aws.access.key.id": "$AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID", - "_sqs.credentials.provider.sts.aws.secret.key.id": "$AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY", + "sqs.credentials.provider.sts.aws.access.key.id": "$AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_ACCESS_KEY_ID", + "sqs.credentials.provider.sts.aws.secret.key.id": "$AWS_ACCOUNT_WITH_ASSUME_ROLE_AWS_SECRET_ACCESS_KEY", "confluent.license": "", "confluent.topic.bootstrap.servers": "broker:9092", "confluent.topic.replication.factor": "1", @@ -111,76 +112,4 @@ playground connector create-or-update --connector sqs-source << EOF EOF log "Verify we have received the data in test-sqs-source topic" -playground topic consume --topic test-sqs-source --min-expected-messages 2 --timeout 60 - - -# [2025-03-21 09:11:30,583] WARN /connectors/sqs-source/config (org.eclipse.jetty.server.HttpChannel:776) -# javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: java.lang.IllegalAccessError: class software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder tried to access private field software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.overrideConfig (software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder and software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder are in unnamed module of loader org.apache.kafka.connect.runtime.isolation.PluginClassLoader @5f7b97da) -# at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:410) -# at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346) -# at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:358) -# at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:311) -# at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205) -# at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) -# at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:554) -# at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) -# at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) -# at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) -# at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440) -# at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) -# at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505) -# at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) -# at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) -# at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355) -# at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) -# at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:234) -# at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:181) -# at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) -# at org.eclipse.jetty.server.Server.handle(Server.java:516) -# at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487) -# at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732) -# at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479) -# at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) -# at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) -# at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) -# at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) -# at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338) -# at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315) -# at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173) -# at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) -# at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409) -# at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) -# at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) -# at java.base/java.lang.Thread.run(Unknown Source) -# Caused by: org.glassfish.jersey.server.ContainerException: java.lang.IllegalAccessError: class software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder tried to access private field software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.overrideConfig (software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder and software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder are in unnamed module of loader org.apache.kafka.connect.runtime.isolation.PluginClassLoader @5f7b97da) -# at org.glassfish.jersey.servlet.internal.ResponseWriter.rethrow(ResponseWriter.java:255) -# at org.glassfish.jersey.servlet.internal.ResponseWriter.failure(ResponseWriter.java:237) -# at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:438) -# at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:263) -# at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) -# at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244) -# at org.glassfish.jersey.internal.Errors.process(Errors.java:292) -# at org.glassfish.jersey.internal.Errors.process(Errors.java:274) -# at org.glassfish.jersey.internal.Errors.process(Errors.java:244) -# at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265) -# at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:234) -# at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684) -# at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394) -# ... 35 more -# Caused by: java.lang.IllegalAccessError: class software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder tried to access private field software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.overrideConfig (software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder and software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder are in unnamed module of loader org.apache.kafka.connect.runtime.isolation.PluginClassLoader @5f7b97da) -# at software.amazon.awssdk.awscore.client.builder.AwsDefaultClientBuilder.setOverrides(AwsDefaultClientBuilder.java:205) -# at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.asyncClientConfiguration(SdkDefaultClientBuilder.java:212) -# at software.amazon.awssdk.services.sqs.DefaultSqsAsyncClientBuilder.buildClient(DefaultSqsAsyncClientBuilder.java:37) -# at software.amazon.awssdk.services.sqs.DefaultSqsAsyncClientBuilder.buildClient(DefaultSqsAsyncClientBuilder.java:25) -# at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.build(SdkDefaultClientBuilder.java:155) -# at io.confluent.connect.sqs.util.SqsClientUtil.createAsyncClient(SqsClientUtil.java:46) -# at io.confluent.connect.sqs.source.SqsSourceConfigValidation.performValidation(SqsSourceConfigValidation.java:89) -# at io.confluent.connect.utils.validators.all.ConfigValidation.validate(ConfigValidation.java:185) -# at io.confluent.connect.sqs.source.SqsSourceConnector.validate(SqsSourceConnector.java:80) -# at org.apache.kafka.connect.runtime.AbstractHerder.validateConnectorConfig(AbstractHerder.java:745) -# at org.apache.kafka.connect.runtime.AbstractHerder.lambda$validateConnectorConfig$5(AbstractHerder.java:597) -# at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) -# at java.base/java.util.concurrent.FutureTask.run(Unknown Source) -# at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) -# at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) -# ... 1 more \ No newline at end of file +playground topic consume --topic test-sqs-source --min-expected-messages 2 --timeout 60 \ No newline at end of file From effb5b3d0fca0eb4b3823b342cba88408ddb5b48 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 21 Mar 2025 12:20:23 +0100 Subject: [PATCH 303/659] update --- scripts/cli/tag-list.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/cli/tag-list.txt b/scripts/cli/tag-list.txt index fa5f678350..69ac7f91d8 100644 --- a/scripts/cli/tag-list.txt +++ b/scripts/cli/tag-list.txt @@ -171,6 +171,7 @@ 7.4.6 7.4.7 7.4.8 +7.4.9 7.5.0 7.5.1 7.5.2 @@ -185,9 +186,12 @@ 7.6.2 7.6.3 7.6.4 +7.6.5 7.7.0 7.7.1 7.7.2 +7.7.3 7.8.0 7.8.1 +7.8.2 7.9.0 From a6bdfc0e26859040e74cc892da9cbc5d9451618f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 24 Mar 2025 09:45:10 +0100 Subject: [PATCH 304/659] 2.30.31 sdk --- .../connect-aws-sqs-source/awscredentialsprovider-v2/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connect/connect-aws-sqs-source/awscredentialsprovider-v2/pom.xml b/connect/connect-aws-sqs-source/awscredentialsprovider-v2/pom.xml index c5e37c0d18..afa964246f 100644 --- a/connect/connect-aws-sqs-source/awscredentialsprovider-v2/pom.xml +++ b/connect/connect-aws-sqs-source/awscredentialsprovider-v2/pom.xml @@ -12,7 +12,7 @@ UTF-8 6.2.0 2.8.0 - 2.29.35 + 2.30.31 From b9d8ca7fe2f04c1c445041400f8a0d55f6689220 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 24 Mar 2025 10:09:44 +0100 Subject: [PATCH 305/659] update --- ccloud/fm-snowflake-sink/README.md | 18 +++--------------- ccloud/fm-snowflake-sink/ui.jpg | Bin 26155 -> 0 bytes ccloud/fm-snowflake-sink/ui.png | Bin 0 -> 62432 bytes connect/connect-snowflake-sink/README.md | 18 +++--------------- secrets.tar.gpg | Bin 7781 -> 7780 bytes 5 files changed, 6 insertions(+), 30 deletions(-) delete mode 100644 ccloud/fm-snowflake-sink/ui.jpg create mode 100644 ccloud/fm-snowflake-sink/ui.png diff --git a/ccloud/fm-snowflake-sink/README.md b/ccloud/fm-snowflake-sink/README.md index 32609b6b6f..0a7e385d47 100644 --- a/ccloud/fm-snowflake-sink/README.md +++ b/ccloud/fm-snowflake-sink/README.md @@ -8,23 +8,11 @@ Quickly test [Snowflake Sink](https://docs.confluent.io/cloud/current/connectors Go to [Snowflake](https://www.snowflake.com) and register an account. You'll receive an email to setup your account and access to a 30 day trial instance. -To get the `SNOWFLAKE_ACCOUNT_NAME`, go there and click on url: +To get the `SNOWFLAKE_ACCOUNT_NAME`, get the *Account Locator* from: -![ui](ui.jpg) +![ui](ui.png) -This will give you an url like: - -``` -https://.snowflakecomputing.com -``` - -Example: - -``` -https://MZLPQCM-DW39774.snowflakecomputing.com -``` - -`SNOWFLAKE_ACCOUNT_NAME` should be set with `MZLPQCM-DW39774` +`SNOWFLAKE_ACCOUNT_NAME` should be set with `..` (for example `XXXXX.eu-west-3.aws`) ## Prerequisites diff --git a/ccloud/fm-snowflake-sink/ui.jpg b/ccloud/fm-snowflake-sink/ui.jpg deleted file mode 100644 index c58205e0759c26011a9885605e747ec628e1af23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26155 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 lU764mU_7!&83Ri>b>u) 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 literal 0 HcmV?d00001 diff --git a/connect/connect-snowflake-sink/README.md b/connect/connect-snowflake-sink/README.md index d6dcbebeba..c43b095d5b 100644 --- a/connect/connect-snowflake-sink/README.md +++ b/connect/connect-snowflake-sink/README.md @@ -12,23 +12,11 @@ Quickly test [Snowflake Sink](https://docs.snowflake.com/en/user-guide/kafka-con Go to [Snowflake](https://www.snowflake.com) and register an account. You'll receive an email to setup your account and access to a 30 day trial instance. -To get the `SNOWFLAKE_ACCOUNT_NAME`, go there and click on url: +To get the `SNOWFLAKE_ACCOUNT_NAME`, get the *Account Locator* from: -![ui](ui.jpg) +![ui](ui.png) -This will give you an url like: - -``` -https://.snowflakecomputing.com -``` - -Example: - -``` -https://MZLPQCM-DW39774.snowflakecomputing.com -``` - -`SNOWFLAKE_ACCOUNT_NAME` should be set with `MZLPQCM-DW39774` +`SNOWFLAKE_ACCOUNT_NAME` should be set with `..` (for example `XXXXX.eu-west-3.aws`) ## How to run diff --git a/secrets.tar.gpg b/secrets.tar.gpg index 4d707f813dad1d4ab96373c76f8bf871d97ec883..4f3979a2d92a626087e91bc1eae622f8639650c2 100644 GIT binary patch literal 7780 zcmV-q9-HBe4Fm}T0<2)DIOEb~c<|Ed0lm2EdQgL=cyNLpG|2T>Q}QUB&FBJ78L9`& z3_6b0sEmg%E7$G^e>WGM>MWffXO&7;*gKsm*T{4;ZJ88k%7r_q_0~Em8!}B1F+$#| z4m;ZgoMruCd$N7bxB=QTafxTv_j$IxMuR!K>|TA)BFwiA0^k&A^QRZvvCG1Cz-t*g z6#3i7gvvud8f&=!x8vG^Sz9_1pm{P1{y43AtE;dNGtWS=5jRT~d z6$TU|#9(5q1fBV?i_C7qJBQBM#IqfX{W-nqdFxrv?@l>#vF}0;?v(ZHVhU4huvakF z)`1C-;oWdiYaMSQXOp%#0?nfS?g=UEsb?_ z&HdnJJ^pjNT3ux>GjSMGi|ld_D~)yBU~C}Szz(%sy2fKtyawvk1CasVRoP6)P0`BM z4dQm^CF{GMD($LdPyt~xm1WM?<5izxf;(q*-!Pnt4&|)+lS-tMnfwZ`_CZ<+Hj`qE z*I;ZnE8zJ3HDflFa341D=7~ZzD9<$v6w%e0opR3^j5=FVF{*Lf|D-QHtTmvR%|YGd zBUdp$^a8#R=nSi_8@WZ6vJRB~&~>XHKScp1Dn}SZpHw;A2(!-;H0hy*N(-CBlsjr$ zk~J1G7-wC3b;3WR*AW|%%?V@JY+?VTMby8_FUfx7b7Fyl%kG{%8rr1+M#rU3GI0X^ zIGEMpld4YRRngOKa6Qo6-0i2QmLkt%(xN%NF%G8|#8C>(9(+Y(5Uz);iFH13EGlSN z6iB9X3~PZ}<3X()QkMjcO$Ra#KQO@h3517WW+6f3O{1)eNLtoSAMXpf;}|UETn&?z z{H8cuPbIKIPe?F}vqbI)V<*`HHUR5WhFvXrPYVOGAKhnS<0`>^h*4p1qj-GaK##?T<>E8n-R<*YQ6b=gQXqGR-Px(} zVF}OgKV{}dN43U=+0oqj0?lComNQ`f6$2mj_*)KPbS~3I#`Mz?R&uaeZvo*hJ{N&& zbeoG{hu+gCT_}1R-xpApKTG=sUXmT~IX3a23Os{jVyq_5<}(ph5}a;Od$?Qpz~S!i zhxj4ArZ}Lp>YEiNP6DzJ1>AZp1HR5<(j?s=aDX=hc~Y9^PTK>}`c_6M3w;x{x_!X+Y&WlHEq0U?TI zA60J`|C7=<6vKlz8-eA>u^Ew?$tgcVK8l%?(gb**zRvY(f}OIXipYaZ?}CT357lvA zz*&1c%Y^#H{-9tkTcp(HJ7^FgL@DNQG4r4z)b%$HCl+0L^h zZ4@{%_3WSP#N+d=bSlfqn%x`xm{dQ2zxQ?s5mWxa;m87xok)QQ^hb!+|9qtqWnRX`OZ^gBdQ|A2@sofh zlS&)m3}Un>p6{s zdARMHLr3g{f-)CgT{)leNENdeU(fuXOr~bOW&&OBXO_zVh&Kp7>jblP-dWaR`#St; z<$LnAu!6+ZaP2pke^a=c!NxZX{&lJriINjGANw9J^4iwQa)e>7E z;Ie|?fyOIY#!}BBaf=_WW7VB}AT~yu_|2srYFriR>4e@VU{MVb2oM?qu3|Q8&Uo^n z*)ecfb9+Bz6iixK>IQCi2)Q#p#yViCzYK0YIW#se$t9EEFx*Zav8)oGHiy0*_qtt7 z-rtuY}faI4+}&z~N?!6Y@y$J5&X*p`PMr9=C^ z_CB=LN=)Co%G>GEFk-|0jWUMQm0=HjXF|^7-Sp)4x4=DSj5|L`k)@A~M>dL@+Nv=A z-@E({_IM$wzI() zB#{sp{xz60QZhQxD&b~n**_`tA0H~iSVk17^0r>*(n(h<+YDhyN?qL3L5hR^ZHy=>g)zfD0Wd3ASUV0)9mZ5`Gn=# z@tWPPKh@;z({YX$JU?|KB3H&GPVW=AHtXwx$K_=ug0|h7W(Kc!Eq+R45b)!Q2No2} zn;p#I)0(8u(#(#6GqT>gjIi3Mc~Q~-+<`J3lEQcb%VeqQmO~&71ZFLmQUw@|C|R=Q z1-=ag(|so>Nzu{(JRJKPDP^kJ)3y8ip4@Z_=?d*N<6@=P&9}RGGvUoi7g666%&Y=P zGKlne^L)(@{*9=Ft4x;H-kH?7--@JfMF=cMrFY)z{4mbg@eS207j;}}zL73PG-=F* zc~V;^ih4ec^FzsVat{UQvxt!Zaz{l>sMT=tB6%`2{B&Y6*&djNxjL0erTKb>zL1ca_#(iBVc zB3Y7oq1+&08h>2r8Uz*g#O`qI9O5^6Ia@}oZ=Uju6G)-44@^qm^-V~DL{H8KFXAt= z6=|#U{`(y1i%P+qsCF}SOv3)Ysxfspp;b~NY|PaNiOT%IbL^GshQ|hItKYoQthDZh z-0VWahgwgS%<3a2#>Vqxjp$6k={2dvC+l_J7P#~QkqN5p7!eAdmP0mV((wjdc7^hp z(E~GN`P(0+l&QI~*L+;&r=`XShPNedJO^K)&9zAyj>0iA1^_|lj;}4}Z{5Vl3#BS6 zPhZ6Zr^xnDSXs#{41&loU4H?!17F?GY=c`_J6+IKT^R*I#bMGf1#J2SAm$j)PWl;- z^l&n~xhH%s@UX=TqMJFrSNyYl3{2wD2n(kW{Y-1RWv0u_rx~ys>5oguCeSn33FDq! z#l^4x;9hbAZW2M~2(JSC=yZfZ;D8IKZf?Uo?F8`uB??>mocI-j(sIk4^BHe$81mk* zO*InW9vsYFAKCG5Hs+7X2r><2u~hfRLN(?x71RB)Nzi5jo5VIU%R9R0p6orMUqpWm z9wrRT-Xp6OY6?5EeOZ#k&Yl6L9w<3aiwc2@fd|7m5>-WeYAcD7ni2g6YB#hbG5o&C ze1s+IWZ-NgIPCp!n=&q!0}ON%&^*)8iQ|$ZIwVG7O{}+gc)pM zI*wg!9fZt83g+e&>iba?;U_ao^?eZD&bWNYQ_(7rx+=Z50MS1>9ecbpG$q6F%F?c87!;9?3$54mtb45Q$gCAptrKQ)7rOX6gxD9NIF4?Q!)UZ9&7 zH0DHKf>Dp=4EJSj#_|RFFqin0v66zwkwyfG=QK979{v8~5T(0$L`>Z=XK zv{*CTB4n)ojv^dOa<|B0bGO-%30OV#Q>H!RHR(I;gtY+w@+Xz#U#i|B)_4!pE=3Hm zr9x9nN^8zksNZsy6;saWTB=7^GB+~7fkib0Y;pnN z*@@yus+T#x%?=C8yb^1|#XNhth=4%cT`x2%O{24s4pZ^tz??cb zZeyU&ZIrfL(&Iabh)+CLBHU-zS(tK!-$v5;vw+W~mSs4c0S0|SHj=VhY&KBZVg27O zC;V^R24}@*?OxS&rtaCWCuK@IL@rk%9>wt>_6!dZ-4twqb-c%%_WNpXfov7kxibopD3_2R0vAMJ@LYXB*Zon!Z9^A=->)k9bzkhLP)V|5ap^B<5 z|0dlCRd{qmJfrr92_BFdyDwC{)Zb<7M<+VTHG0N7>zY5ktp&8vnRrGBA-)@jBdEbV zImNiD!4yr>5KRfyH|@)Dh7aO^+B$i)iU>U6(b2XQHk zQfLKfQdcgq4*Q3-(}HF5V_lgT=BL;8FLQ=07;f#&L*5t$G@gHe{SanU9HDjll@#4< zZ=R00>vj)L6X-X{+;D$Es)``8lA4LV7qm&x-6}6&P;@=$bZ|Sg4(Mmz_RtpNn*g9s z>Ah^$j25Y}+S+3t83eSHgRmvPYb=^gNGY8(UK$h%$m?io2W;Q^3D5%MB{nKYEu;F= z5EZoFHG$N{k~eaT%BWtMrVlTyM0Em{irKe1#IA*=utCPb-rhP4R`$I1{0Vz$MT-uh zKOPXaLsP{uzm~1fFryZ$+ZE11Yn;>4rzf=oPK0@htzMDJWQUMxziJ1b)oXtT!&P=>RIYSk0J ztcZS3)J3D5d^YH4q*eDQh^;uM9wK85mUXdH0}yz_P0z<%ss?NadCJNRI4e5{K0@M( zc3iAq7Ty?m*|Jw(31~oM$iBcfRhs&v-{Xr z@{#HCozDzV2$EM4!7g5#fi{6Ng?DvxH+y8ykMZTef80q&fz>x0q?kYQpmqRdzNQbN z2YyTU{9?vTh2aL%5%D%Cj1TaMP5y4ajGMgrP?;Vr-jw6`MD)pxc2EcceuD zSWTmFyt4|Xt8Sdwa)^$gIs^Za{7u-CCTL9VR@PUbEzEDfVcfN3@eEbB`3{aK1jnj6TczW%`eC3h>t~u|q9+KMmMe6pe{sUc z|BYdvEh_i2aS2h8S;Xs*(FU3Dr7sM=^Bd&qX4o(Ky3+yeP@n9vsE(&m+O6tm^e4#| zE43GXdvtyBMb&Fv%#dty{A>(JHyIu&-jQRru?8(2Ii5owj}Uk^73>NMr5gw*f2&>6{Ay{68c4)`-WN(*?(L2g;o=# zZjp<}&TrJ+Zv`s=!!gs?Tt?L{Z5gxn1LMJ6p{C6S_iGHHhvIOrt<*VanoIisSm|-0;Vu`J|D|ePp=PN;FBQ>y=hWaL-YzERv zq@wWXA(HyhwYw&j28W+_+6p^$A%Nf2dFyLDfl6y3z$jYNQtJ=>5oxwX+%`Jins5pP*R8Qs&a(R5|04unomX&W_7F1#wZHP%0 zSdT9I!Cvp{cRbOTevhJr50BbEDKVay~#`ZmD8N9ih zK9-HEl32ypKFVO@=IZ88N0X~3F5AS(&(Xj^>4$9mgV&-<4O=`;N0$N7N74UEN*c>h zU}E{>)0ht=7g?0=VfOG$)8;)u5zM&>YIxF!NT~ly>xJyWzK@e)IV3v(w(L_qDj0KL zP}H9jY^D#}9LMa*L$FHnQRimPh6GsW@~%6XOGi8WFuYv{sf zMEta#vfzs>iW`nMydUbns^6A_QG(E=zud{6N)}Jtblp z!Xv8VF}ZDV7;#cjvQr(8lum_S#I`vKGtgY}4wr&BeF?N$&9gL-!E)HSk#C)x`7htj z5xis2TM3;&}5(oa5 z{5xlm30v1)N=aqp`7wS;-Q;~Am+G-PrZ^B?Z&8oKgw$11*izFYB?l0C#l^ybiaG(& zOa3(FJXm^`h)4g0&H)PPtO3ZQdNA0S8Y8i{1g${J2&6#~b{JeTDuIT*HXxb1s9fobQybJw%hv` z*_F{8s|l=GH?RT}WD6o$@0`|RHdk7sH67)!ZY8mra?-2;<47sCO`*5g7~4hrg|lTS z(jG4xUlREnXe85~@yl;l(z7Ks>ds?s?#D>X=@2C=0_db9Ew$JNVw zpxc>cB9`Su!b{P=6?y;)up_0n6*s_xP_#hfguzy2@}=!GUDDIk@fCRCLR2Xs6S#&@ zE_?XxdWJa`ztr24)r)(MS}vGA+AQNN*E6-H(lDNYsi^kDXhJ8@cv|t2DQG?CGgDh; zyiea~JIfIvDl`Lg8q&eCkJsCmn<#4CmCnh^x9TH|OE4EV=Oxg1g!)RKz(Fgjz66Wa6?RKu5cUHMT(gc&XEapJeFA z^``yvroRluAyyj&=k+nSce=#|I47`|I%j!IsK!~av`FapBmHmWJ(H=C{vxHgu@z}D zzxwc)%9!*_`oKPOgr83ZmQ(4dB)2QcV zAq7V%&CMG2Jxn24KHwg(?xY{2eE@>Wz;*Sh$lft#_Ofa`jf6Zy6O+FLtP4M2bK6;| z3C6=pg_G&!qu89$JkABE_$)?maEyCslS%2HJ-3~Bm;whA*bJq%W?*JcPes)DR{~h@ zztrC{wFo7Ni#(Cg<+AW~9?Fjyr(pmq&p_-TofYad&2Kz;cfey(DckWjqGqs)QGLOa zT!Ti;^Th|-^~<|hG{IAhhFos^?aATb@y|wwKi7ir8ZjIw zN@9{`{Du3Z^C2l=Rm5u~4?`rGBHu9{KJOz3?&0UF>H33-n-C2UbM?rer*ei)UMy-c zRND(&tn)pOL09k&?rwUF(C1+&Us8o$o^oTJ0>_>%)P*=&f40!Y?S^J`GbBTUn}YL- zZQAvM7FP&Uff&W-SC<5Fx91Uyj|FMyL@oZ?9CGj;>iN%hZKF!D`MH#=EhUN(MOhfV z2Bs63OyNVMCQ&r>buwmUo{ z+WxwNJT3AyNu8!x_J;g8Ye(#++5F0vcyFBsFnWEV1I#DE(oeF*uvhlK4G|5gq-3e{ z0&*73q#e#_mRj5MT00^@5wk%)uWaHT4Epv-n3t#65L0Q+Cw(w2@|Ay-fK4mpp_pR) zevwMZzTOt#atGaEhPW%6T?9Vq&*@zP2~@27uX2uOWNSTell$db?4)tY2PjXJd!sCy zsEiPaV3Z(s-|`(uUyxl7XVF@)9*$kRBL5*c;olUD4QXveHjLv0EoWHgEmi)Ct&ybD zpk-i@K(WN?7H?eO#_p$rc?BAwZGaAv<9dvbHlQ}&L%9@u>FvQLc;bVaHo_7*U0|%k zDQK6ym+{Kt?xOAqiC#gSsMiftEF-!MfL)1rp`D_91J1bB?O8Krn91n*OpNvb`r1E3 zr&WQWI~N5{tE8w@)aePe7jXWak~%6G?+jZgleBITP?)C?&s9%2iK5th?T+sG@89SD z!4uHO?r$K1%ioaznK`!rs~5y8i3e$bf<~sl{j^v3{-ab}c6{ zriMhEPf_n6ne|b`k9TBy71Ni|uH~0Q+&6Lu6P6#9EYID@m2ygnQDL)L*E;Zqx{Pba zrw)ZwIHYZuN=eXBB{3QGspHpq7CU>YA??+ICqAv819Kt(unWUE} z+W_$?9u_AJgQ0JNG>eW}JK)xq%3MYLokTf$B5QP-ZEKZ+eC8|O7`FsUum^KnXZ#Wn zb|_N%YnVn;DJjP1PGXpjpf3|S%z5jw#>|t_4Z$3Rlpki_61&C01m-y0G`n)BB0@5X q#(6@Uq}-W6ng*WT`tqZK-&JvWOG=gF?)DO2o@r1^D^k6=v#TEJ9U%Jv literal 7781 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 rhfX@P5Gzj$B_h*F^pK9(^P7= Date: Mon, 24 Mar 2025 13:16:29 +0100 Subject: [PATCH 306/659] wip --- secrets.tar.gpg | Bin 7780 -> 7834 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/secrets.tar.gpg b/secrets.tar.gpg index 4f3979a2d92a626087e91bc1eae622f8639650c2..99e2a9b3f98a380de6160d1455545449d5a524a2 100644 GIT binary patch literal 7834 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 From 3983d8976399f13bb8829a0d9069fb217c49a694 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 25 Mar 2025 09:22:01 +0100 Subject: [PATCH 307/659] SALESFORCE_CONSUMER_PASSWORD_WITH_JWT is not needed --- .github/workflows/ci.yml | 2 -- ccloud/fm-salesforce-cdc-source/README.md | 2 +- .../fully-managed-salesforce-cdc-source-jwt-flow.sh | 6 ------ connect/connect-salesforce-cdc-source/README.md | 6 +++--- .../salesforce-cdc-source-jwt-flow.sh | 7 ------- 5 files changed, 4 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 933ecc7f6f..14cc0fb508 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -270,7 +270,6 @@ jobs: SALESFORCE_CONSUMER_KEY_ACCOUNT2: ${{ secrets.SALESFORCE_CONSUMER_KEY_ACCOUNT2}} SALESFORCE_CONSUMER_PASSWORD_ACCOUNT2: ${{ secrets.SALESFORCE_CONSUMER_PASSWORD_ACCOUNT2}} SALESFORCE_CONSUMER_KEY_WITH_JWT: ${{ secrets.SALESFORCE_CONSUMER_KEY_WITH_JWT}} - SALESFORCE_CONSUMER_PASSWORD_WITH_JWT: ${{ secrets.SALESFORCE_CONSUMER_PASSWORD_WITH_JWT}} DD_API_KEY: ${{ secrets.DD_API_KEY}} DD_APP_KEY: ${{ secrets.DD_APP_KEY}} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME}} @@ -461,7 +460,6 @@ jobs: SALESFORCE_CONSUMER_KEY_ACCOUNT2: ${{ secrets.SALESFORCE_CONSUMER_KEY_ACCOUNT2}} SALESFORCE_CONSUMER_PASSWORD_ACCOUNT2: ${{ secrets.SALESFORCE_CONSUMER_PASSWORD_ACCOUNT2}} SALESFORCE_CONSUMER_KEY_WITH_JWT: ${{ secrets.SALESFORCE_CONSUMER_KEY_WITH_JWT}} - SALESFORCE_CONSUMER_PASSWORD_WITH_JWT: ${{ secrets.SALESFORCE_CONSUMER_PASSWORD_WITH_JWT}} DD_API_KEY: ${{ secrets.DD_API_KEY}} DD_APP_KEY: ${{ secrets.DD_APP_KEY}} DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME}} diff --git a/ccloud/fm-salesforce-cdc-source/README.md b/ccloud/fm-salesforce-cdc-source/README.md index aa9e184972..0afb3bc4a9 100644 --- a/ccloud/fm-salesforce-cdc-source/README.md +++ b/ccloud/fm-salesforce-cdc-source/README.md @@ -110,7 +110,7 @@ Example: ![Create a connected app](jwt-bearer-authentication1.jpg) * Save the connected app, it takes between 2 and 10 minutes to be activated. -* Look for the Consumer Key `SALESFORCE_CONSUMER_KEY_WITH_JWT` and Consumer Secret `SALESFORCE_CONSUMER_PASSWORD_WITH_JWT`in the displayed form. Save these so you can put them in the configuration for the Salesforce connector. +* Look for the Consumer Key `SALESFORCE_CONSUMER_KEY_WITH_JWT` in the displayed form. Save these so you can put them in the configuration for the Salesforce connector. ### Pre-Approve the connected app with the User-Agent OAuth Flow diff --git a/ccloud/fm-salesforce-cdc-source/fully-managed-salesforce-cdc-source-jwt-flow.sh b/ccloud/fm-salesforce-cdc-source/fully-managed-salesforce-cdc-source-jwt-flow.sh index bd7ed68226..0376c43318 100755 --- a/ccloud/fm-salesforce-cdc-source/fully-managed-salesforce-cdc-source-jwt-flow.sh +++ b/ccloud/fm-salesforce-cdc-source/fully-managed-salesforce-cdc-source-jwt-flow.sh @@ -30,12 +30,6 @@ then exit 1 fi -if [ -z "$SALESFORCE_CONSUMER_PASSWORD_WITH_JWT" ] -then - logerror "SALESFORCE_CONSUMER_PASSWORD_WITH_JWT is not set. Export it as environment variable or pass it as argument. Check README !" - exit 1 -fi - if [ -z "$SALESFORCE_SECURITY_TOKEN" ] then logerror "SALESFORCE_SECURITY_TOKEN is not set. Export it as environment variable or pass it as argument" diff --git a/connect/connect-salesforce-cdc-source/README.md b/connect/connect-salesforce-cdc-source/README.md index 5345ca66b3..44b4ad084a 100644 --- a/connect/connect-salesforce-cdc-source/README.md +++ b/connect/connect-salesforce-cdc-source/README.md @@ -63,13 +63,13 @@ Search for "Change Data Capture" in Settings and then select `Contact`: Simply run: ``` -$ just use command and search for salesforce-cdc-source .sh in this folder +$ just use command and search for salesforce-cdc-source ``` or with JWT flow: ``` -$ just use command and search for salesforce-cdc-source-jwt-flow .sh in this folder +$ just use command and search for salesforce-cdc-source-jwt-flow ``` Note: you can also export these values as environment variable @@ -698,7 +698,7 @@ Example: ![Create a connected app](jwt-bearer-authentication1.jpg) * Save the connected app, it takes between 2 and 10 minutes to be activated. -* Look for the Consumer Key `SALESFORCE_CONSUMER_KEY_WITH_JWT` and Consumer Secret `SALESFORCE_CONSUMER_PASSWORD_WITH_JWT`in the displayed form. Save these so you can put them in the configuration for the Salesforce connector. +* Look for the Consumer Key `SALESFORCE_CONSUMER_KEY_WITH_JWT` in the displayed form. Save these so you can put them in the configuration for the Salesforce connector. ### Pre-Approve the connected app with the User-Agent OAuth Flow diff --git a/connect/connect-salesforce-cdc-source/salesforce-cdc-source-jwt-flow.sh b/connect/connect-salesforce-cdc-source/salesforce-cdc-source-jwt-flow.sh index 7cc014ef18..3667dbc866 100755 --- a/connect/connect-salesforce-cdc-source/salesforce-cdc-source-jwt-flow.sh +++ b/connect/connect-salesforce-cdc-source/salesforce-cdc-source-jwt-flow.sh @@ -36,12 +36,6 @@ then exit 1 fi -if [ -z "$SALESFORCE_CONSUMER_PASSWORD_WITH_JWT" ] -then - logerror "SALESFORCE_CONSUMER_PASSWORD_WITH_JWT is not set. Export it as environment variable or pass it as argument. Check README !" - exit 1 -fi - if [ -z "$SALESFORCE_SECURITY_TOKEN" ] then logerror "SALESFORCE_SECURITY_TOKEN is not set. Export it as environment variable or pass it as argument" @@ -86,7 +80,6 @@ playground connector create-or-update --connector salesforce-cdc-source << EOF "confluent.topic.replication.factor": "1", "salesforce.consumer.key" : "$SALESFORCE_CONSUMER_KEY_WITH_JWT", - "salesforce.consumer.secret" : "$SALESFORCE_CONSUMER_PASSWORD_WITH_JWT", "salesforce.jwt.keystore.path": "/tmp/salesforce-confluent.keystore.jks", "salesforce.jwt.keystore.password": "confluent" } From 2e405da4716edda94e21879be024675b59fc6001 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 25 Mar 2025 09:27:19 +0100 Subject: [PATCH 308/659] remove unrequired fields --- .../salesforce-cdc-source-jwt-flow.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/connect/connect-salesforce-cdc-source/salesforce-cdc-source-jwt-flow.sh b/connect/connect-salesforce-cdc-source/salesforce-cdc-source-jwt-flow.sh index 3667dbc866..41b8278953 100755 --- a/connect/connect-salesforce-cdc-source/salesforce-cdc-source-jwt-flow.sh +++ b/connect/connect-salesforce-cdc-source/salesforce-cdc-source-jwt-flow.sh @@ -69,8 +69,6 @@ playground connector create-or-update --connector salesforce-cdc-source << EOF "__comment" : "from 2.0.0 salesforce.cdc.name is renamed salesforce.cdc.channel", "salesforce.cdc.channel" : "ContactChangeEvent", "salesforce.username" : "$SALESFORCE_USERNAME", - "salesforce.password" : "$SALESFORCE_PASSWORD", - "salesforce.password.token" : "$SALESFORCE_SECURITY_TOKEN", "salesforce.initial.start" : "latest", "connection.max.message.size": "10048576", "key.converter": "org.apache.kafka.connect.json.JsonConverter", From 2efbfafb3b514bd1c8327d307f91a295aecf9bb8 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 25 Mar 2025 10:48:03 +0100 Subject: [PATCH 309/659] =?UTF-8?q?=F0=9F=A7=A0=20playground=20schema=20de?= =?UTF-8?q?rive-schema:=20handle=20non-minified=20json=20#6394?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 13 +++++++++++++ scripts/cli/src/commands/schema/derive-schema.sh | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/scripts/cli/playground b/scripts/cli/playground index 864fb31eb7..13eb049a14 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -18832,6 +18832,19 @@ playground_schema_derive_schema_command() { fi fi + if jq -e . >/dev/null 2>&1 <<< "$(head -1 "$payload_file")" + then + log "💫 payload is one json per line, one json record per line will be used" + elif jq -e . >/dev/null 2>&1 <<< "$(cat "$payload_file")" + then + log "💫 payload is single json, it will be used as one record" + jq -c . "$payload_file" > $tmp_dir/minified.json + cp $tmp_dir/minified.json $payload_file + else + logerror "❌ payload is not a valid json" + exit 1 + fi + LATEST_TAG=$(grep "export TAG" $root_folder/scripts/utils.sh | head -1 | cut -d "=" -f 2 | cut -d " " -f 1) if [ -z "$LATEST_TAG" ] then diff --git a/scripts/cli/src/commands/schema/derive-schema.sh b/scripts/cli/src/commands/schema/derive-schema.sh index caf9fb7288..24053117c9 100644 --- a/scripts/cli/src/commands/schema/derive-schema.sh +++ b/scripts/cli/src/commands/schema/derive-schema.sh @@ -38,6 +38,19 @@ else fi fi +if jq -e . >/dev/null 2>&1 <<< "$(head -1 "$payload_file")" +then + log "💫 payload is one json per line, one json record per line will be used" +elif jq -e . >/dev/null 2>&1 <<< "$(cat "$payload_file")" +then + log "💫 payload is single json, it will be used as one record" + jq -c . "$payload_file" > $tmp_dir/minified.json + cp $tmp_dir/minified.json $payload_file +else + logerror "❌ payload is not a valid json" + exit 1 +fi + LATEST_TAG=$(grep "export TAG" $root_folder/scripts/utils.sh | head -1 | cut -d "=" -f 2 | cut -d " " -f 1) if [ -z "$LATEST_TAG" ] then From f84fc6309a2fb2cfa1d76451fca6a72d2d08910f Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Tue, 25 Mar 2025 12:34:02 +0100 Subject: [PATCH 310/659] do not check for schema existence --- scripts/cli/playground | 52 ++++++++++----------- scripts/cli/src/commands/schema/register.sh | 52 ++++++++++----------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 13eb049a14..cdd7bc56d3 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -18468,33 +18468,33 @@ playground_schema_register_command() { # check if schema already exists # https://docs.confluent.io/platform/current/schema-registry/develop/api.html#post--subjects-(string-%20subject) - curl_output=$(curl $sr_security --request POST -s "${sr_url}/subjects/${subject}" \ - --header 'Content-Type: application/vnd.schemaregistry.v1+json' \ - --data "$json_new" | jq .) - ret=$? - if [ $ret -eq 0 ] - then - if echo "$curl_output" | jq '. | has("error_code")' 2> /dev/null | grep -q true + # curl_output=$(curl $sr_security --request POST -s "${sr_url}/subjects/${subject}" \ + # --header 'Content-Type: application/vnd.schemaregistry.v1+json' \ + # --data "$json_new" | jq .) + # ret=$? + # if [ $ret -eq 0 ] + # then + # if echo "$curl_output" | jq '. | has("error_code")' 2> /dev/null | grep -q true - then - error_code=$(echo "$curl_output" | jq -r .error_code) - if [ "$error_code" != "40403" ] && [ "$error_code" != "40401" ] - then - message=$(echo "$curl_output" | jq -r .message) - logerror "Command failed with error code $error_code" - logerror "$message" - exit 1 - fi - else - id=$(echo "$curl_output" | jq -r .id) - version=$(echo "$curl_output" | jq -r .version) - log "🚪 Skipping as schema already exists with id $id (version $version)" - exit 0 - fi - else - logerror "❌ curl request failed with error code $ret!" - exit 1 - fi + # then + # error_code=$(echo "$curl_output" | jq -r .error_code) + # if [ "$error_code" != "40403" ] && [ "$error_code" != "40401" ] + # then + # message=$(echo "$curl_output" | jq -r .message) + # logerror "Command failed with error code $error_code" + # logerror "$message" + # exit 1 + # fi + # else + # id=$(echo "$curl_output" | jq -r .id) + # version=$(echo "$curl_output" | jq -r .version) + # log "🚪 Skipping as schema already exists with id $id (version $version)" + # exit 0 + # fi + # else + # logerror "❌ curl request failed with error code $ret!" + # exit 1 + # fi log "⏺️ Registering schema to subject ${subject}" if [[ -n "$verbose" ]] diff --git a/scripts/cli/src/commands/schema/register.sh b/scripts/cli/src/commands/schema/register.sh index 2383de2120..39e262fdec 100644 --- a/scripts/cli/src/commands/schema/register.sh +++ b/scripts/cli/src/commands/schema/register.sh @@ -157,32 +157,32 @@ fi # check if schema already exists # https://docs.confluent.io/platform/current/schema-registry/develop/api.html#post--subjects-(string-%20subject) -curl_output=$(curl $sr_security --request POST -s "${sr_url}/subjects/${subject}" \ ---header 'Content-Type: application/vnd.schemaregistry.v1+json' \ ---data "$json_new" | jq .) -ret=$? -if [ $ret -eq 0 ] -then - if echo "$curl_output" | jq '. | has("error_code")' 2> /dev/null | grep -q true - then - error_code=$(echo "$curl_output" | jq -r .error_code) - if [ "$error_code" != "40403" ] && [ "$error_code" != "40401" ] - then - message=$(echo "$curl_output" | jq -r .message) - logerror "Command failed with error code $error_code" - logerror "$message" - exit 1 - fi - else - id=$(echo "$curl_output" | jq -r .id) - version=$(echo "$curl_output" | jq -r .version) - log "🚪 Skipping as schema already exists with id $id (version $version)" - exit 0 - fi -else - logerror "❌ curl request failed with error code $ret!" - exit 1 -fi +# curl_output=$(curl $sr_security --request POST -s "${sr_url}/subjects/${subject}" \ +# --header 'Content-Type: application/vnd.schemaregistry.v1+json' \ +# --data "$json_new" | jq .) +# ret=$? +# if [ $ret -eq 0 ] +# then +# if echo "$curl_output" | jq '. | has("error_code")' 2> /dev/null | grep -q true +# then +# error_code=$(echo "$curl_output" | jq -r .error_code) +# if [ "$error_code" != "40403" ] && [ "$error_code" != "40401" ] +# then +# message=$(echo "$curl_output" | jq -r .message) +# logerror "Command failed with error code $error_code" +# logerror "$message" +# exit 1 +# fi +# else +# id=$(echo "$curl_output" | jq -r .id) +# version=$(echo "$curl_output" | jq -r .version) +# log "🚪 Skipping as schema already exists with id $id (version $version)" +# exit 0 +# fi +# else +# logerror "❌ curl request failed with error code $ret!" +# exit 1 +# fi log "⏺️ Registering schema to subject ${subject}" if [[ -n "$verbose" ]] From 91b7dee09831916269a7db8ba3c4759eefa90ec7 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 26 Mar 2025 15:23:30 +0100 Subject: [PATCH 311/659] do not use jvm level jks --- .../docker-compose.plaintext.mtls-db-auth.yml | 16 ++++++++-------- .../docker-compose.plaintext.mtls.yml | 12 ++++++------ .../docker-compose.plaintext.ssl.yml | 6 +++--- .../oracle19-sink-mtls-db-auth.sh | 4 ++++ .../oracle19-sink-mtls.sh | 4 ++++ .../oracle19-sink-ssl.sh | 2 ++ 6 files changed, 27 insertions(+), 17 deletions(-) diff --git a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls-db-auth.yml b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls-db-auth.yml index 028320f14c..ee2d5d6880 100644 --- a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls-db-auth.yml +++ b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls-db-auth.yml @@ -21,11 +21,11 @@ services: - ../../connect/connect-jdbc-oracle19-sink/mtls/keystore.jks:/tmp/keystore.jks environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc - # need to set oracle variables at JVM level because DDEC-2996 (Allow additional properties to be passed to the JDBC driver) was only added in 10.x - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - -Djavax.net.ssl.keyStore=/tmp/keystore.jks - -Djavax.net.ssl.keyStorePassword=welcome123 - -Doracle.net.ssl_server_dn_match=true - -Doracle.net.authentication_services="(TCPS)" - # -Djavax.net.debug=all \ No newline at end of file + # # need to set oracle variables at JVM level because DDEC-2996 (Allow additional properties to be passed to the JDBC driver) was only added in 10.x + # KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks + # -Djavax.net.ssl.trustStorePassword=welcome123 + # -Djavax.net.ssl.keyStore=/tmp/keystore.jks + # -Djavax.net.ssl.keyStorePassword=welcome123 + # -Doracle.net.ssl_server_dn_match=true + # -Doracle.net.authentication_services="(TCPS)" + # # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls.yml b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls.yml index 652c186f2a..b8f23fd04a 100644 --- a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls.yml +++ b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.mtls.yml @@ -22,9 +22,9 @@ services: environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc # need to set oracle variables at JVM level because DDEC-2996 (Allow additional properties to be passed to the JDBC driver) was only added in 10.x - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - -Djavax.net.ssl.keyStore=/tmp/keystore.jks - -Djavax.net.ssl.keyStorePassword=welcome123 - -Doracle.net.ssl_server_dn_match=true - # -Djavax.net.debug=all \ No newline at end of file + # KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks + # -Djavax.net.ssl.trustStorePassword=welcome123 + # -Djavax.net.ssl.keyStore=/tmp/keystore.jks + # -Djavax.net.ssl.keyStorePassword=welcome123 + # -Doracle.net.ssl_server_dn_match=true + # # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.ssl.yml b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.ssl.yml index 94282009af..63fe21e720 100644 --- a/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.ssl.yml +++ b/connect/connect-jdbc-oracle19-sink/docker-compose.plaintext.ssl.yml @@ -21,7 +21,7 @@ services: environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc # need to set oracle variables at JVM level because DDEC-2996 (Allow additional properties to be passed to the JDBC driver) was only added in 10.x - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - -Doracle.net.ssl_server_dn_match=true + # KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks + # -Djavax.net.ssl.trustStorePassword=welcome123 + # -Doracle.net.ssl_server_dn_match=true # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh index db67df9a00..96a1183388 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh @@ -157,6 +157,10 @@ playground connector create-or-update --connector oracle-sink-mtls-db-auth << E "connection.oracle.net.ssl_server_dn_match": "true", "connection.oracle.net.authentication_services": "(TCPS)", "connection.url": "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=oracle)(PORT=1532))(CONNECT_DATA=(SERVICE_NAME=ORCLCDB))(SECURITY=(SSL_SERVER_CERT_DN=\"CN=server,C=US\")))", + "connection.javax.net.ssl.trustStore": "/tmp/truststore.jks", + "connection.javax.net.ssl.trustStorePassword": "welcome123", + "connection.javax.net.ssl.keyStore": "/tmp/keystore.jks", + "connection.javax.net.ssl.keyStorePassword": "welcome123", "topics": "ORDERS", "auto.create": "true", "insert.mode":"insert", diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh index c2ed892fd2..4159c6aee7 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh @@ -153,6 +153,10 @@ playground connector create-or-update --connector oracle-sink-mtls << EOF "connection.password": "mypassword", "connection.oracle.net.ssl_server_dn_match": "true", "connection.url": "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=oracle)(PORT=1532))(CONNECT_DATA=(SERVICE_NAME=ORCLCDB))(SECURITY=(SSL_SERVER_CERT_DN=\"CN=server,C=US\")))", + "connection.javax.net.ssl.trustStore": "/tmp/truststore.jks", + "connection.javax.net.ssl.trustStorePassword": "welcome123", + "connection.javax.net.ssl.keyStore": "/tmp/keystore.jks", + "connection.javax.net.ssl.keyStorePassword": "welcome123", "topics": "ORDERS", "auto.create": "true", "insert.mode":"insert", diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh index f9e413fb09..75caa8eab7 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh @@ -124,6 +124,8 @@ playground connector create-or-update --connector oracle-sink-ssl << EOF "connection.password": "mypassword", "connection.oracle.net.ssl_server_dn_match": "true", "connection.url": "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=oracle)(PORT=1532))(CONNECT_DATA=(SERVICE_NAME=ORCLCDB))(SECURITY=(SSL_SERVER_CERT_DN=\"CN=server,C=US\")))", + "connection.javax.net.ssl.trustStore": "/tmp/truststore.jks", + "connection.javax.net.ssl.trustStorePassword": "welcome123", "topics": "ORDERS", "auto.create": "true", "insert.mode":"insert", From 01c8bc92a0519cc6f96815693a6250674981ef54 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Wed, 26 Mar 2025 15:25:22 +0100 Subject: [PATCH 312/659] do not use jdk jks --- .../docker-compose.plaintext.mtls-db-auth.yml | 12 +++--- .../docker-compose.plaintext.mtls.yml | 10 ++--- .../docker-compose.plaintext.ssl.yml | 6 +-- .../oracle19-mtls-db-auth.sh | 40 +++++++++--------- .../oracle19-mtls.sh | 42 +++++++++---------- .../oracle19-ssl.sh | 2 + 6 files changed, 57 insertions(+), 55 deletions(-) diff --git a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls-db-auth.yml b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls-db-auth.yml index 9911009959..34830e8ca0 100644 --- a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls-db-auth.yml +++ b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls-db-auth.yml @@ -22,10 +22,10 @@ services: environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc # need to set oracle variables at JVM level because DDEC-2996 (Allow additional properties to be passed to the JDBC driver) was only added in 10.x - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - -Djavax.net.ssl.keyStore=/tmp/keystore.jks - -Djavax.net.ssl.keyStorePassword=welcome123 - -Doracle.net.ssl_server_dn_match=true - -Doracle.net.authentication_services="(TCPS)" + # KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks + # -Djavax.net.ssl.trustStorePassword=welcome123 + # -Djavax.net.ssl.keyStore=/tmp/keystore.jks + # -Djavax.net.ssl.keyStorePassword=welcome123 + # -Doracle.net.ssl_server_dn_match=true + # -Doracle.net.authentication_services="(TCPS)" # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls.yml b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls.yml index ecd31e79e7..3e93a42bd9 100644 --- a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls.yml +++ b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.mtls.yml @@ -22,9 +22,9 @@ services: environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc # need to set oracle variables at JVM level because DDEC-2996 (Allow additional properties to be passed to the JDBC driver) was only added in 10.x - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - -Djavax.net.ssl.keyStore=/tmp/keystore.jks - -Djavax.net.ssl.keyStorePassword=welcome123 - -Doracle.net.ssl_server_dn_match=true + # KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks + # -Djavax.net.ssl.trustStorePassword=welcome123 + # -Djavax.net.ssl.keyStore=/tmp/keystore.jks + # -Djavax.net.ssl.keyStorePassword=welcome123 + # -Doracle.net.ssl_server_dn_match=true # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.ssl.yml b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.ssl.yml index 1fd8f71eca..4771ff0df3 100644 --- a/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.ssl.yml +++ b/connect/connect-jdbc-oracle19-source/docker-compose.plaintext.ssl.yml @@ -21,7 +21,7 @@ services: environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-jdbc # need to set oracle variables at JVM level because DDEC-2996 (Allow additional properties to be passed to the JDBC driver) was only added in 10.x - KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks - -Djavax.net.ssl.trustStorePassword=welcome123 - -Doracle.net.ssl_server_dn_match=true + # KAFKA_OPTS: -Djavax.net.ssl.trustStore=/tmp/truststore.jks + # -Djavax.net.ssl.trustStorePassword=welcome123 + # -Doracle.net.ssl_server_dn_match=true # -Djavax.net.debug=all \ No newline at end of file diff --git a/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh b/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh index f32a0841b9..9c7ed294f2 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh @@ -185,26 +185,26 @@ sleep 10 log "Creating Oracle source connector" playground connector create-or-update --connector oracle-source-mtls-db-auth << EOF { - "connector.class":"io.confluent.connect.jdbc.JdbcSourceConnector", - "tasks.max":"1", - "connection.oracle.net.ssl_server_dn_match": "true", - "connection.oracle.net.authentication_services": "(TCPS)", - "connection.url": "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=oracle)(PORT=1532))(CONNECT_DATA=(SERVICE_NAME=ORCLCDB))(SECURITY=(SSL_SERVER_CERT_DN=\"CN=server,C=US\")))", - "numeric.mapping":"best_fit", - "mode":"timestamp", - "poll.interval.ms":"1000", - "validate.non.null":"false", - "schema.pattern": "C##MYUSER", - "table.whitelist":"CUSTOMERS", - "timestamp.column.name":"UPDATE_TS", - "topic.prefix":"oracle-", - "errors.log.enable": "true", - "errors.log.include.messages": "true", - - "connection.javax.net.ssl.trustStore": "/tmp/truststore.jks", - "connection.javax.net.ssl.trustStorePassword": "welcome123", - "connection.javax.net.ssl.keyStore": "/tmp/keystore.jks", - "connection.javax.net.ssl.keyStorePassword": "welcome123" + "connector.class":"io.confluent.connect.jdbc.JdbcSourceConnector", + "tasks.max":"1", + "connection.oracle.net.ssl_server_dn_match": "true", + "connection.oracle.net.authentication_services": "(TCPS)", + "connection.url": "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=oracle)(PORT=1532))(CONNECT_DATA=(SERVICE_NAME=ORCLCDB))(SECURITY=(SSL_SERVER_CERT_DN=\"CN=server,C=US\")))", + "numeric.mapping":"best_fit", + "mode":"timestamp", + "poll.interval.ms":"1000", + "validate.non.null":"false", + "schema.pattern": "C##MYUSER", + "table.whitelist":"CUSTOMERS", + "timestamp.column.name":"UPDATE_TS", + "topic.prefix":"oracle-", + "errors.log.enable": "true", + "errors.log.include.messages": "true", + + "connection.javax.net.ssl.trustStore": "/tmp/truststore.jks", + "connection.javax.net.ssl.trustStorePassword": "welcome123", + "connection.javax.net.ssl.keyStore": "/tmp/keystore.jks", + "connection.javax.net.ssl.keyStorePassword": "welcome123" } EOF diff --git a/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh b/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh index 443016ac13..5476eeb247 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh @@ -179,27 +179,27 @@ sleep 10 log "Creating Oracle source connector" playground connector create-or-update --connector oracle-source-mtls << EOF { - "connector.class":"io.confluent.connect.jdbc.JdbcSourceConnector", - "tasks.max":"1", - "connection.user": "C##MYUSER", - "connection.password": "mypassword", - "connection.oracle.net.ssl_server_dn_match": "true", - "connection.url": "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=oracle)(PORT=1532))(CONNECT_DATA=(SERVICE_NAME=ORCLCDB))(SECURITY=(SSL_SERVER_CERT_DN=\"CN=server,C=US\")))", - "numeric.mapping":"best_fit", - "mode":"timestamp", - "poll.interval.ms":"1000", - "validate.non.null":"false", - "schema.pattern": "C##MYUSER", - "table.whitelist":"CUSTOMERS", - "timestamp.column.name":"UPDATE_TS", - "topic.prefix":"oracle-", - "errors.log.enable": "true", - "errors.log.include.messages": "true", - "connection.javax.net.ssl.trustStore": "/tmp/truststore.jks", - "connection.javax.net.ssl.trustStorePassword": "welcome123", - "connection.javax.net.ssl.keyStore": "/tmp/keystore.jks", - "connection.javax.net.ssl.keyStorePassword": "welcome123" -} + "connector.class":"io.confluent.connect.jdbc.JdbcSourceConnector", + "tasks.max":"1", + "connection.user": "C##MYUSER", + "connection.password": "mypassword", + "connection.oracle.net.ssl_server_dn_match": "true", + "connection.url": "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=oracle)(PORT=1532))(CONNECT_DATA=(SERVICE_NAME=ORCLCDB))(SECURITY=(SSL_SERVER_CERT_DN=\"CN=server,C=US\")))", + "connection.javax.net.ssl.trustStore": "/tmp/truststore.jks", + "connection.javax.net.ssl.trustStorePassword": "welcome123", + "connection.javax.net.ssl.keyStore": "/tmp/keystore.jks", + "connection.javax.net.ssl.keyStorePassword": "welcome123", + "numeric.mapping":"best_fit", + "mode":"timestamp", + "poll.interval.ms":"1000", + "validate.non.null":"false", + "schema.pattern": "C##MYUSER", + "table.whitelist":"CUSTOMERS", + "timestamp.column.name":"UPDATE_TS", + "topic.prefix":"oracle-", + "errors.log.enable": "true", + "errors.log.include.messages": "true" + } EOF sleep 5 diff --git a/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh b/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh index 85b5bfc86e..d4bc09a569 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh @@ -157,6 +157,8 @@ playground connector create-or-update --connector oracle-source-ssl << EOF "connection.password": "mypassword", "connection.oracle.net.ssl_server_dn_match": "true", "connection.url": "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=oracle)(PORT=1532))(CONNECT_DATA=(SERVICE_NAME=ORCLCDB))(SECURITY=(SSL_SERVER_CERT_DN=\"CN=server,C=US\")))", + "connection.javax.net.ssl.trustStore": "/tmp/truststore.jks", + "connection.javax.net.ssl.trustStorePassword": "welcome123", "numeric.mapping":"best_fit", "mode":"timestamp", "poll.interval.ms":"1000", From 8c54ab98da817d919721a37d21cf9936e82569ab Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 27 Mar 2025 10:17:37 +0100 Subject: [PATCH 313/659] update --- scripts/cli/confluent-hub-plugin-list.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/cli/confluent-hub-plugin-list.txt b/scripts/cli/confluent-hub-plugin-list.txt index 942fa051d1..3dcdd773a2 100644 --- a/scripts/cli/confluent-hub-plugin-list.txt +++ b/scripts/cli/confluent-hub-plugin-list.txt @@ -222,7 +222,6 @@ splunk/kafka-connect-splunk spoudinc/spoud-agoora startree/startree-native-integration streaming-dev-lab/secured-flow -streamsendio/file-chunk-sink streamsendio/file-chunk-source streamsets/streamsets-sdc swim/swim-kafka-connect From eda6b8b3c8d765924afc4870d86f3b78b3697207 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 27 Mar 2025 13:46:34 +0100 Subject: [PATCH 314/659] fix #6382 --- ccloud/fm-azure-service-bus-source/QueuesGettingStarted/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ccloud/fm-azure-service-bus-source/QueuesGettingStarted/pom.xml b/ccloud/fm-azure-service-bus-source/QueuesGettingStarted/pom.xml index da8972f909..108d260906 100644 --- a/ccloud/fm-azure-service-bus-source/QueuesGettingStarted/pom.xml +++ b/ccloud/fm-azure-service-bus-source/QueuesGettingStarted/pom.xml @@ -49,7 +49,7 @@ com.microsoft.azure azure-servicebus - 1.2.8 + 3.6.5 org.slf4j From 697235c103ae3491e570bcd934c270eb8a101fd6 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 27 Mar 2025 13:46:43 +0100 Subject: [PATCH 315/659] fix #6377 --- .../QueuesGettingStarted/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connect/connect-azure-service-bus-source/QueuesGettingStarted/pom.xml b/connect/connect-azure-service-bus-source/QueuesGettingStarted/pom.xml index da8972f909..108d260906 100644 --- a/connect/connect-azure-service-bus-source/QueuesGettingStarted/pom.xml +++ b/connect/connect-azure-service-bus-source/QueuesGettingStarted/pom.xml @@ -49,7 +49,7 @@ com.microsoft.azure azure-servicebus - 1.2.8 + 3.6.5 org.slf4j From d809c7ffff99b7616193b0e7b8a510a3a89dd11d Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 27 Mar 2025 15:23:25 +0100 Subject: [PATCH 316/659] #6395 CONNECT_TAG -> CP_CONNECT_TAG --- ...docker-compose-connect-onprem-to-cloud.yml | 2 +- ccloud/environment/docker-compose.yml | 2 +- ...ed-debezium-legacy-sqlserver-source-ssl.sh | 2 +- ...anaged-debezium-v2-sqlserver-source-ssl.sh | 2 +- .../fully-managed-mysql-source-ssl.sh | 4 +- .../fully-managed-jdbc-oracle19-source-ssl.sh | 4 +- ...ker-compose-executable-onprem-to-cloud.yml | 2 +- ccloud/multiple-sr-hybrid/README.md | 2 +- ccloud/multiple-sr-hybrid/docker-compose.yml | 2 +- .../docker-compose-cloud-to-cloud.yml | 2 +- ...ect-onprem-to-cloud-with-sr-basic-auth.yml | 2 +- ...docker-compose-connect-onprem-to-cloud.yml | 2 +- ...ompose-executable-onprem-to-cloud-avro.yml | 2 +- ...ker-compose-executable-onprem-to-cloud.yml | 2 +- .../cdc-oracle12-cdb-table-mtls-db-auth.sh | 14 +-- .../cdc-oracle12-cdb-table-mtls.sh | 14 +-- .../cdc-oracle12-cdb-table-ssl.sh | 4 +- .../cdc-oracle12-pdb-table-mtls-db-auth.sh | 14 +-- .../cdc-oracle12-pdb-table-mtls.sh | 14 +-- .../cdc-oracle12-pdb-table-ssl.sh | 4 +- .../cdc-oracle18-cdb-table-mtls-db-auth.sh | 14 +-- .../cdc-oracle18-cdb-table-mtls.sh | 14 +-- .../cdc-oracle18-cdb-table-ssl.sh | 4 +- .../cdc-oracle18-pdb-table-mtls.sh | 14 +-- .../cdc-oracle18-pdb-table-ssl.sh | 4 +- .../cdc-oracle19-cdb-table-mtls-db-auth.sh | 14 +-- .../cdc-oracle19-cdb-table-mtls.sh | 14 +-- .../cdc-oracle19-cdb-table-ssl.sh | 4 +- .../cdc-oracle19-pdb-table-mtls-db-auth.sh | 14 +-- .../cdc-oracle19-pdb-table-mtls.sh | 14 +-- .../cdc-oracle19-pdb-table-ssl.sh | 4 +- .../cdc-oracle21-cdb-table-mtls-db-auth.sh | 14 +-- .../cdc-oracle21-cdb-table-mtls.sh | 14 +-- .../cdc-oracle21-cdb-table-ssl.sh | 4 +- .../cdc-oracle21-pdb-table-mtls-db-auth.sh | 14 +-- .../cdc-oracle21-pdb-table-mtls.sh | 14 +-- .../cdc-oracle21-pdb-table-ssl.sh | 4 +- .../debezium-sqlserver-source-ssl.sh | 2 +- .../ibmdb2-sink-ssl.sh | 4 +- .../ibmdb2-source-ssl.sh | 4 +- .../mysql-sink-mtls.sh | 4 +- .../connect-jdbc-mysql-sink/mysql-sink-ssl.sh | 4 +- .../connect-jdbc-mysql-source/mysql-mtls.sh | 4 +- .../connect-jdbc-mysql-source/mysql-ssl.sh | 4 +- .../oracle12-sink-mtls-db-auth.sh | 14 +-- .../oracle12-sink-mtls.sh | 14 +-- .../oracle12-sink-ssl.sh | 4 +- .../oracle12-mtls-db-auth.sh | 14 +-- .../oracle12-mtls.sh | 14 +-- .../oracle12-ssl.sh | 4 +- .../oracle19-sink-mtls-db-auth.sh | 14 +-- .../oracle19-sink-mtls.sh | 14 +-- .../oracle19-sink-ssl.sh | 4 +- .../oracle19-mtls-db-auth.sh | 14 +-- .../oracle19-mtls.sh | 14 +-- .../oracle19-ssl.sh | 4 +- .../oracle21-sink-mtls-db-auth.sh | 14 +-- .../oracle21-sink-mtls.sh | 14 +-- .../oracle21-sink-ssl.sh | 4 +- .../oracle21-mtls-db-auth.sh | 14 +-- .../oracle21-mtls.sh | 14 +-- .../oracle21-ssl.sh | 4 +- .../sqlserver-jtds-sink-ssl.sh | 2 +- .../sqlserver-microsoft-sink-ssl.sh | 2 +- .../sqlserver-jtds-ssl.sh | 2 +- .../sqlserver-microsoft-ssl.sh | 2 +- .../connect-mongodb-sink/mongo-sink-ssl.sh | 2 +- .../mongo-source-ssl.sh | 2 +- environment/mdc-kerberos/start.sh | 2 +- environment/mdc-plaintext/docker-compose.yml | 4 +- environment/mdc-plaintext/start.sh | 2 +- environment/mdc-sasl-plain/start.sh | 2 +- environment/plaintext/docker-compose.yml | 6 +- environment/rbac-sasl-plain/start.sh | 4 +- .../rbac/04-start-remaining-components.sh | 46 ++++----- .../docker-compose.plaintext.yml | 4 +- reproduction-models | 2 +- scripts/cli/playground | 98 +++++++++---------- .../commands/connector-plugin/search-jar.sh | 2 +- .../cli/src/commands/connector/show-lag.sh | 2 +- .../cli/src/commands/container/recreate.sh | 4 +- .../container/set-environment-variables.sh | 2 +- .../cli/src/commands/get-docker-compose.sh | 2 +- scripts/cli/src/commands/tcp-proxy/start.sh | 2 +- .../cli/src/commands/tools/certs-create.sh | 4 +- scripts/cli/src/commands/topic/alter.sh | 2 +- scripts/cli/src/commands/topic/consume.sh | 6 +- scripts/cli/src/commands/topic/create.sh | 2 +- scripts/cli/src/commands/topic/delete.sh | 2 +- scripts/cli/src/commands/topic/describe.sh | 2 +- scripts/cli/src/commands/topic/produce.sh | 44 ++++----- scripts/cli/src/lib/utils_function.sh | 22 ++--- scripts/utils.sh | 52 +++++----- .../docker-compose.add-connect-worker.yml | 2 +- .../docker-compose.yml | 6 +- 95 files changed, 416 insertions(+), 416 deletions(-) diff --git a/ccloud/connect-centralized-license/docker-compose-connect-onprem-to-cloud.yml b/ccloud/connect-centralized-license/docker-compose-connect-onprem-to-cloud.yml index 7d736568f4..ba12969cb9 100644 --- a/ccloud/connect-centralized-license/docker-compose-connect-onprem-to-cloud.yml +++ b/ccloud/connect-centralized-license/docker-compose-connect-onprem-to-cloud.yml @@ -47,7 +47,7 @@ services: SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: broker:9092 connect: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-replicator CONNECT_REST_EXTENSION_CLASSES: io.confluent.connect.replicator.monitoring.ReplicatorMonitoringExtension diff --git a/ccloud/environment/docker-compose.yml b/ccloud/environment/docker-compose.yml index 33b93541ef..296e247657 100644 --- a/ccloud/environment/docker-compose.yml +++ b/ccloud/environment/docker-compose.yml @@ -1,7 +1,7 @@ --- services: connect: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} hostname: connect container_name: connect ports: diff --git a/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh b/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh index 98d1a3f522..747e14c55f 100755 --- a/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh +++ b/ccloud/fm-debezium-sqlserver-legacy-source/fully-managed-debezium-legacy-sqlserver-source-ssl.sh @@ -37,7 +37,7 @@ fi log "Creating JKS from pem files" rm -f truststore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MSSQLCACert -noprompt -file /tmp/mssql.pem -keystore /tmp/truststore.jks -storepass confluent +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importcert -alias MSSQLCACert -noprompt -file /tmp/mssql.pem -keystore /tmp/truststore.jks -storepass confluent if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh b/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh index c9f4e923c3..c9997e686f 100755 --- a/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh +++ b/ccloud/fm-debezium-sqlserver-v2-source/fully-managed-debezium-v2-sqlserver-source-ssl.sh @@ -37,7 +37,7 @@ fi log "Creating JKS from pem files" rm -f truststore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MSSQLCACert -noprompt -file /tmp/mssql.pem -keystore /tmp/truststore.jks -storepass confluent +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importcert -alias MSSQLCACert -noprompt -file /tmp/mssql.pem -keystore /tmp/truststore.jks -storepass confluent if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/ccloud/fm-jdbc-mysql-source/fully-managed-mysql-source-ssl.sh b/ccloud/fm-jdbc-mysql-source/fully-managed-mysql-source-ssl.sh index 7e60c05a47..70f045d623 100755 --- a/ccloud/fm-jdbc-mysql-source/fully-managed-mysql-source-ssl.sh +++ b/ccloud/fm-jdbc-mysql-source/fully-managed-mysql-source-ssl.sh @@ -44,7 +44,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword # Convert the client key and certificate files to a PKCS #12 archive docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 if [[ "$OSTYPE" == "darwin"* ]] @@ -58,7 +58,7 @@ else ls -lrt fi # Import the client key and certificate into a Java keystore: -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword cd - log "Create table" diff --git a/ccloud/fm-jdbc-oracle19-source/fully-managed-jdbc-oracle19-source-ssl.sh b/ccloud/fm-jdbc-oracle19-source/fully-managed-jdbc-oracle19-source-ssl.sh index fb81c963fb..9bcfedeb8f 100755 --- a/ccloud/fm-jdbc-oracle19-source/fully-managed-jdbc-oracle19-source-ssl.sh +++ b/ccloud/fm-jdbc-oracle19-source/fully-managed-jdbc-oracle19-source-ssl.sh @@ -126,9 +126,9 @@ else ls -lrt fi # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/ccloud/migrate-schemas-to-confluent-cloud/docker-compose-executable-onprem-to-cloud.yml b/ccloud/migrate-schemas-to-confluent-cloud/docker-compose-executable-onprem-to-cloud.yml index 1eb0c003a0..3282aae25f 100644 --- a/ccloud/migrate-schemas-to-confluent-cloud/docker-compose-executable-onprem-to-cloud.yml +++ b/ccloud/migrate-schemas-to-confluent-cloud/docker-compose-executable-onprem-to-cloud.yml @@ -48,5 +48,5 @@ services: SCHEMA_REGISTRY_MODE_MUTABILITY: "true" connect: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} entrypoint: ["sh", "-c", "sleep 2073600"] \ No newline at end of file diff --git a/ccloud/multiple-sr-hybrid/README.md b/ccloud/multiple-sr-hybrid/README.md index a396d373c1..4e3cf69086 100644 --- a/ccloud/multiple-sr-hybrid/README.md +++ b/ccloud/multiple-sr-hybrid/README.md @@ -26,7 +26,7 @@ Here is the container: ```yml webserver: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} hostname: webserver container_name: webserver depends_on: diff --git a/ccloud/multiple-sr-hybrid/docker-compose.yml b/ccloud/multiple-sr-hybrid/docker-compose.yml index 6613c1a56b..2476df1822 100644 --- a/ccloud/multiple-sr-hybrid/docker-compose.yml +++ b/ccloud/multiple-sr-hybrid/docker-compose.yml @@ -6,7 +6,7 @@ services: KAFKA_CONFLUENT_SCHEMA_REGISTRY_URL: http://schema-registry:8081 webserver: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} hostname: webserver container_name: webserver depends_on: diff --git a/ccloud/replicator/docker-compose-cloud-to-cloud.yml b/ccloud/replicator/docker-compose-cloud-to-cloud.yml index abc08e7b7a..14ece97bbb 100644 --- a/ccloud/replicator/docker-compose-cloud-to-cloud.yml +++ b/ccloud/replicator/docker-compose-cloud-to-cloud.yml @@ -2,7 +2,7 @@ services: connect: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-replicator CONNECT_REST_EXTENSION_CLASSES: io.confluent.connect.replicator.monitoring.ReplicatorMonitoringExtension diff --git a/ccloud/replicator/docker-compose-connect-onprem-to-cloud-with-sr-basic-auth.yml b/ccloud/replicator/docker-compose-connect-onprem-to-cloud-with-sr-basic-auth.yml index 1d866cd26c..1a46295237 100644 --- a/ccloud/replicator/docker-compose-connect-onprem-to-cloud-with-sr-basic-auth.yml +++ b/ccloud/replicator/docker-compose-connect-onprem-to-cloud-with-sr-basic-auth.yml @@ -54,7 +54,7 @@ services: - ../../multi-data-center/replicator-connect/password-file:/tmp/password-file connect: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-replicator CONNECT_REST_EXTENSION_CLASSES: io.confluent.connect.replicator.monitoring.ReplicatorMonitoringExtension diff --git a/ccloud/replicator/docker-compose-connect-onprem-to-cloud.yml b/ccloud/replicator/docker-compose-connect-onprem-to-cloud.yml index a0f3ef1208..df5300ff83 100644 --- a/ccloud/replicator/docker-compose-connect-onprem-to-cloud.yml +++ b/ccloud/replicator/docker-compose-connect-onprem-to-cloud.yml @@ -47,7 +47,7 @@ services: SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: broker:9092 connect: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} environment: CONNECT_PLUGIN_PATH: /usr/share/confluent-hub-components/confluentinc-kafka-connect-replicator CONNECT_REST_EXTENSION_CLASSES: io.confluent.connect.replicator.monitoring.ReplicatorMonitoringExtension diff --git a/ccloud/replicator/docker-compose-executable-onprem-to-cloud-avro.yml b/ccloud/replicator/docker-compose-executable-onprem-to-cloud-avro.yml index 96d1ea4ee8..ac194fd568 100644 --- a/ccloud/replicator/docker-compose-executable-onprem-to-cloud-avro.yml +++ b/ccloud/replicator/docker-compose-executable-onprem-to-cloud-avro.yml @@ -47,5 +47,5 @@ services: SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: broker:9092 connect: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} entrypoint: ["sh", "-c", "sleep 2073600"] \ No newline at end of file diff --git a/ccloud/replicator/docker-compose-executable-onprem-to-cloud.yml b/ccloud/replicator/docker-compose-executable-onprem-to-cloud.yml index 96d1ea4ee8..ac194fd568 100644 --- a/ccloud/replicator/docker-compose-executable-onprem-to-cloud.yml +++ b/ccloud/replicator/docker-compose-executable-onprem-to-cloud.yml @@ -47,5 +47,5 @@ services: SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: broker:9092 connect: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} entrypoint: ["sh", "-c", "sleep 2073600"] \ No newline at end of file diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls-db-auth.sh index c8d7768d5c..98b306154d 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls-db-auth.sh @@ -135,10 +135,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -154,7 +154,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -167,16 +167,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh index 28ef91ce32..d6ad42188d 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-mtls.sh @@ -135,10 +135,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -154,7 +154,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -167,16 +167,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh index 5d3dfbb751..46274159ac 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-cdb-table-ssl.sh @@ -146,9 +146,9 @@ else ls -lrt fi # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh index 8b336541b4..c020c1b6da 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls-db-auth.sh @@ -149,10 +149,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -168,7 +168,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -181,16 +181,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh index d7ec507d64..3baa69ea74 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-mtls.sh @@ -147,10 +147,10 @@ fi log "Create a JKS keystore" rm -f keystore.jks # Create a new private/public key pair for 'CN=connect,C=US' -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -166,7 +166,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -179,16 +179,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh index 7616894413..bb71911f95 100755 --- a/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle12-source/cdc-oracle12-pdb-table-ssl.sh @@ -158,9 +158,9 @@ else ls -lrt fi # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls-db-auth.sh index 84b2268b7a..a7fda6a355 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls-db-auth.sh @@ -135,10 +135,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -154,7 +154,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -167,16 +167,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh index bf79a99725..0dd3e971ce 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-mtls.sh @@ -137,10 +137,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -156,7 +156,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -169,16 +169,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh index 08e7c51ff9..f1c72f500e 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-cdb-table-ssl.sh @@ -146,9 +146,9 @@ else ls -lrt fi # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh index d12b243132..f283172114 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-mtls.sh @@ -147,10 +147,10 @@ fi log "Create a JKS keystore" rm -f keystore.jks # Create a new private/public key pair for 'CN=connect,C=US' -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -166,7 +166,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -179,16 +179,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh index c6f7aa74ba..5e240463ff 100755 --- a/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle18-source/cdc-oracle18-pdb-table-ssl.sh @@ -158,9 +158,9 @@ else ls -lrt fi # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls-db-auth.sh index f999bafaaa..3b3940ecdd 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls-db-auth.sh @@ -131,10 +131,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -150,7 +150,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -163,16 +163,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh index c646906c39..c9a60f6828 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh @@ -131,10 +131,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -150,7 +150,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -163,16 +163,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh index 4df13e9bdb..9ab0a70b6e 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh @@ -142,9 +142,9 @@ else ls -lrt fi # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh index a6e131c73f..7deb2098b2 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh @@ -150,10 +150,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -169,7 +169,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -182,16 +182,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh index 52e06ef7a3..f7fd444f2b 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh @@ -148,10 +148,10 @@ fi log "Create a JKS keystore" rm -f keystore.jks # Create a new private/public key pair for 'CN=connect,C=US' -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -167,7 +167,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -180,16 +180,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh index b3f43653bb..7bb1a5dcbf 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh @@ -159,9 +159,9 @@ else ls -lrt fi # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh index df36e23386..091eb47fdf 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh @@ -131,10 +131,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -150,7 +150,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -163,16 +163,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh index 7f2972c2e3..d1172a58a5 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh @@ -131,10 +131,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -150,7 +150,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -163,16 +163,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh index 6a85ca63b9..98ef052330 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh @@ -142,9 +142,9 @@ else ls -lrt fi # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh index 9877a29ac4..6072dff6bb 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh @@ -150,10 +150,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -169,7 +169,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -182,16 +182,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh index 617190a73c..8595353102 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh @@ -148,10 +148,10 @@ fi log "Create a JKS keystore" rm -f keystore.jks # Create a new private/public key pair for 'CN=connect,C=US' -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -167,7 +167,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -180,16 +180,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh index 9b70353220..bc9d91f78c 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh @@ -159,9 +159,9 @@ else ls -lrt fi # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh index 6a4cc87f99..11a266d568 100755 --- a/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh +++ b/connect/connect-debezium-sqlserver-source/debezium-sqlserver-source-ssl.sh @@ -43,7 +43,7 @@ fi log "Creating JKS from pem files" rm -f truststore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MSSQLCACert -noprompt -file /tmp/mssql.pem -keystore /tmp/truststore.jks -storepass confluent +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importcert -alias MSSQLCACert -noprompt -file /tmp/mssql.pem -keystore /tmp/truststore.jks -storepass confluent if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/connect/connect-jdbc-ibmdb2-sink/ibmdb2-sink-ssl.sh b/connect/connect-jdbc-ibmdb2-sink/ibmdb2-sink-ssl.sh index 5e6a3ecc30..1c4dba541e 100755 --- a/connect/connect-jdbc-ibmdb2-sink/ibmdb2-sink-ssl.sh +++ b/connect/connect-jdbc-ibmdb2-sink/ibmdb2-sink-ssl.sh @@ -88,9 +88,9 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -trustcacerts -v -noprompt -alias myAlias -file /tmp/server.arm -keystore /tmp/truststore.jks -storepass 'confluent' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -trustcacerts -v -noprompt -alias myAlias -file /tmp/server.arm -keystore /tmp/truststore.jks -storepass 'confluent' log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'confluent' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'confluent' -v cd - diff --git a/connect/connect-jdbc-ibmdb2-source/ibmdb2-source-ssl.sh b/connect/connect-jdbc-ibmdb2-source/ibmdb2-source-ssl.sh index 1e52cb82cd..eb4419b0ae 100755 --- a/connect/connect-jdbc-ibmdb2-source/ibmdb2-source-ssl.sh +++ b/connect/connect-jdbc-ibmdb2-source/ibmdb2-source-ssl.sh @@ -88,9 +88,9 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -trustcacerts -v -noprompt -alias myAlias -file /tmp/server.arm -keystore /tmp/truststore.jks -storepass 'confluent' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -trustcacerts -v -noprompt -alias myAlias -file /tmp/server.arm -keystore /tmp/truststore.jks -storepass 'confluent' log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'confluent' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'confluent' -v cd - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" ${profile_control_center_command} ${profile_ksqldb_command} ${profile_grafana_command} ${profile_kcat_command} up -d --quiet-pull diff --git a/connect/connect-jdbc-mysql-sink/mysql-sink-mtls.sh b/connect/connect-jdbc-mysql-sink/mysql-sink-mtls.sh index 2c516d8407..1767553415 100755 --- a/connect/connect-jdbc-mysql-sink/mysql-sink-mtls.sh +++ b/connect/connect-jdbc-mysql-sink/mysql-sink-mtls.sh @@ -42,7 +42,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword # Convert the client key and certificate files to a PKCS #12 archive docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 if [[ "$OSTYPE" == "darwin"* ]] @@ -56,7 +56,7 @@ else ls -lrt fi # Import the client key and certificate into a Java keystore: -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword cd - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.mtls.yml" up -d --quiet-pull diff --git a/connect/connect-jdbc-mysql-sink/mysql-sink-ssl.sh b/connect/connect-jdbc-mysql-sink/mysql-sink-ssl.sh index 337ff4054b..b2e295b619 100755 --- a/connect/connect-jdbc-mysql-sink/mysql-sink-ssl.sh +++ b/connect/connect-jdbc-mysql-sink/mysql-sink-ssl.sh @@ -42,7 +42,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword # Convert the client key and certificate files to a PKCS #12 archive docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 if [[ "$OSTYPE" == "darwin"* ]] @@ -56,7 +56,7 @@ else ls -lrt fi # Import the client key and certificate into a Java keystore: -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword cd - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d --quiet-pull diff --git a/connect/connect-jdbc-mysql-source/mysql-mtls.sh b/connect/connect-jdbc-mysql-source/mysql-mtls.sh index 04f6981e22..524f1a7787 100755 --- a/connect/connect-jdbc-mysql-source/mysql-mtls.sh +++ b/connect/connect-jdbc-mysql-source/mysql-mtls.sh @@ -42,7 +42,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword # Convert the client key and certificate files to a PKCS #12 archive docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 if [[ "$OSTYPE" == "darwin"* ]] @@ -56,7 +56,7 @@ else ls -lrt fi # Import the client key and certificate into a Java keystore: -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword cd - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d --quiet-pull diff --git a/connect/connect-jdbc-mysql-source/mysql-ssl.sh b/connect/connect-jdbc-mysql-source/mysql-ssl.sh index 4abbd27561..25275cfc91 100755 --- a/connect/connect-jdbc-mysql-source/mysql-ssl.sh +++ b/connect/connect-jdbc-mysql-source/mysql-ssl.sh @@ -41,7 +41,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importcert -alias MySQLCACert -noprompt -file /tmp/ca.pem -keystore /tmp/truststore.jks -storepass mypassword # Convert the client key and certificate files to a PKCS #12 archive docker run --quiet --rm -v $PWD:/tmp alpine/openssl pkcs12 -export -in /tmp/client-cert.pem -inkey /tmp/client-key.pem -name "mysqlclient" -passout pass:mypassword -out /tmp/client-keystore.p12 if [[ "$OSTYPE" == "darwin"* ]] @@ -55,7 +55,7 @@ else ls -lrt fi # Import the client key and certificate into a Java keystore: -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importkeystore -srckeystore /tmp/client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore /tmp/keystore.jks -deststoretype JKS -deststorepass mypassword cd - docker compose -f ../../environment/plaintext/docker-compose.yml -f "${PWD}/docker-compose.plaintext.ssl.yml" up -d --quiet-pull diff --git a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh index c2844e44ea..c2eda95ec4 100755 --- a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls-db-auth.sh @@ -72,10 +72,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -91,7 +91,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -104,16 +104,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh index 18bcfad70c..04a65d2326 100755 --- a/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh +++ b/connect/connect-jdbc-oracle12-sink/oracle12-sink-mtls.sh @@ -73,10 +73,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -92,7 +92,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -105,16 +105,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh b/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh index cdd1963da4..dd63dbbb88 100755 --- a/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh +++ b/connect/connect-jdbc-oracle12-sink/oracle12-sink-ssl.sh @@ -84,9 +84,9 @@ else ls -lrt fi # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh b/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh index c8a636e86a..057ed5104c 100755 --- a/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle12-source/oracle12-mtls-db-auth.sh @@ -106,10 +106,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -125,7 +125,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -138,16 +138,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh b/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh index 844913b664..18882593d9 100755 --- a/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh +++ b/connect/connect-jdbc-oracle12-source/oracle12-mtls.sh @@ -106,10 +106,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -125,7 +125,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -138,16 +138,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh b/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh index f9fd5f2123..32c10978cd 100755 --- a/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh +++ b/connect/connect-jdbc-oracle12-source/oracle12-ssl.sh @@ -117,9 +117,9 @@ else ls -lrt fi # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh index 96a1183388..68a160afcf 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls-db-auth.sh @@ -73,10 +73,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -92,7 +92,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -105,16 +105,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh index 4159c6aee7..1da28c92f1 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink-mtls.sh @@ -73,10 +73,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -92,7 +92,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -105,16 +105,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh b/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh index 75caa8eab7..21d4cccbfb 100755 --- a/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh +++ b/connect/connect-jdbc-oracle19-sink/oracle19-sink-ssl.sh @@ -83,9 +83,9 @@ else ls -lrt fi # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh b/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh index 9c7ed294f2..6ae47b1884 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19-mtls-db-auth.sh @@ -106,10 +106,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -125,7 +125,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -138,16 +138,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh b/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh index 5476eeb247..2c4fd39edd 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19-mtls.sh @@ -106,10 +106,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -125,7 +125,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -138,16 +138,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh b/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh index d4bc09a569..bd2e917634 100755 --- a/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh +++ b/connect/connect-jdbc-oracle19-source/oracle19-ssl.sh @@ -117,9 +117,9 @@ else ls -lrt fi # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls-db-auth.sh b/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls-db-auth.sh index fb94721f31..89214c29cf 100755 --- a/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls-db-auth.sh @@ -72,10 +72,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -91,7 +91,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -104,16 +104,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls.sh b/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls.sh index 17fc3988be..2a9421964e 100755 --- a/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls.sh +++ b/connect/connect-jdbc-oracle21-sink/oracle21-sink-mtls.sh @@ -72,10 +72,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -91,7 +91,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -104,16 +104,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle21-sink/oracle21-sink-ssl.sh b/connect/connect-jdbc-oracle21-sink/oracle21-sink-ssl.sh index 7c5bd6345b..ee24de8460 100755 --- a/connect/connect-jdbc-oracle21-sink/oracle21-sink-ssl.sh +++ b/connect/connect-jdbc-oracle21-sink/oracle21-sink-ssl.sh @@ -83,9 +83,9 @@ else ls -lrt fi # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle21-source/oracle21-mtls-db-auth.sh b/connect/connect-jdbc-oracle21-source/oracle21-mtls-db-auth.sh index 0d74d5a6dc..08a47050bf 100755 --- a/connect/connect-jdbc-oracle21-source/oracle21-mtls-db-auth.sh +++ b/connect/connect-jdbc-oracle21-source/oracle21-mtls-db-auth.sh @@ -106,10 +106,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -125,7 +125,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -138,16 +138,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle21-source/oracle21-mtls.sh b/connect/connect-jdbc-oracle21-source/oracle21-mtls.sh index 3a469c9b10..ac50a177e0 100755 --- a/connect/connect-jdbc-oracle21-source/oracle21-mtls.sh +++ b/connect/connect-jdbc-oracle21-source/oracle21-mtls.sh @@ -106,10 +106,10 @@ fi log "Create a JKS keystore" # Create a new private/public key pair for 'CN=connect,C=US' rm -f keystore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -genkey -alias testclient -dname 'CN=connect,C=US' -storepass 'welcome123' -storetype JKS -keystore /tmp/keystore.jks -keyalg RSA # Generate a CSR (Certificate Signing Request): -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -certreq -alias testclient -file /tmp/csr.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Sign the client certificate using the test CA (root) docker cp csr.txt oracle:/tmp/csr.txt docker exec oracle bash -c "orapki cert create -wallet /tmp/root -request /tmp/csr.txt -cert /tmp/cert.txt -validity 3650 -pwd WalletPasswd123" @@ -125,7 +125,7 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -noprompt -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/keystore.jks -storepass 'welcome123' # Import the signed certificate docker cp oracle:/tmp/cert.txt cert.txt if [[ "$OSTYPE" == "darwin"* ]] @@ -138,16 +138,16 @@ else sudo chmod -R a+rw . ls -lrt fi -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testclient -file /tmp/cert.txt -keystore /tmp/keystore.jks -storepass 'welcome123' log "Displaying keystore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/keystore.jks -storepass 'welcome123' -v log "Create a JKS truststore" rm -f truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-oracle21-source/oracle21-ssl.sh b/connect/connect-jdbc-oracle21-source/oracle21-ssl.sh index 95068df330..ca9bbb1f52 100755 --- a/connect/connect-jdbc-oracle21-source/oracle21-ssl.sh +++ b/connect/connect-jdbc-oracle21-source/oracle21-ssl.sh @@ -117,9 +117,9 @@ else ls -lrt fi # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/b64certificate.txt -keystore /tmp/truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/truststore.jks -storepass 'welcome123' -v cd ${DIR} diff --git a/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh b/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh index e9512cb609..29d3e33aaf 100755 --- a/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh +++ b/connect/connect-jdbc-sqlserver-sink/sqlserver-jtds-sink-ssl.sh @@ -46,7 +46,7 @@ fi log "Creating JKS from pem files" rm -f truststore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MSSQLCACert -noprompt -file /tmp/mssql.pem -keystore /tmp/truststore.jks -storepass confluent +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importcert -alias MSSQLCACert -noprompt -file /tmp/mssql.pem -keystore /tmp/truststore.jks -storepass confluent if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh b/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh index 1a81e2bc75..10f96761e6 100755 --- a/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh +++ b/connect/connect-jdbc-sqlserver-sink/sqlserver-microsoft-sink-ssl.sh @@ -47,7 +47,7 @@ fi log "Creating JKS from pem files" rm -f truststore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MSSQLCACert -noprompt -file /tmp/mssql.pem -keystore /tmp/truststore.jks -storepass confluent +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importcert -alias MSSQLCACert -noprompt -file /tmp/mssql.pem -keystore /tmp/truststore.jks -storepass confluent if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh b/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh index fb1ad6269c..1d44a4c33a 100755 --- a/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh +++ b/connect/connect-jdbc-sqlserver-source/sqlserver-jtds-ssl.sh @@ -46,7 +46,7 @@ fi log "Creating JKS from pem files" rm -f truststore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MSSQLCACert -noprompt -file /tmp/mssql.pem -keystore /tmp/truststore.jks -storepass confluent +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importcert -alias MSSQLCACert -noprompt -file /tmp/mssql.pem -keystore /tmp/truststore.jks -storepass confluent if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh b/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh index 7a8e828c2e..c92b39e45a 100755 --- a/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh +++ b/connect/connect-jdbc-sqlserver-source/sqlserver-microsoft-ssl.sh @@ -47,7 +47,7 @@ fi log "Creating JKS from pem files" rm -f truststore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias MSSQLCACert -noprompt -file /tmp/mssql.pem -keystore /tmp/truststore.jks -storepass confluent +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importcert -alias MSSQLCACert -noprompt -file /tmp/mssql.pem -keystore /tmp/truststore.jks -storepass confluent if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/connect/connect-mongodb-sink/mongo-sink-ssl.sh b/connect/connect-mongodb-sink/mongo-sink-ssl.sh index 7c06c8500d..f39641850c 100755 --- a/connect/connect-mongodb-sink/mongo-sink-ssl.sh +++ b/connect/connect-mongodb-sink/mongo-sink-ssl.sh @@ -51,7 +51,7 @@ fi log "Creating JKS from pem files" rm -f truststore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias mongoCACert -noprompt -file /tmp/mongo.crt -keystore /tmp/truststore.jks -storepass confluent +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importcert -alias mongoCACert -noprompt -file /tmp/mongo.crt -keystore /tmp/truststore.jks -storepass confluent if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/connect/connect-mongodb-source/mongo-source-ssl.sh b/connect/connect-mongodb-source/mongo-source-ssl.sh index 9077c4f452..e4eadca8c1 100755 --- a/connect/connect-mongodb-source/mongo-source-ssl.sh +++ b/connect/connect-mongodb-source/mongo-source-ssl.sh @@ -51,7 +51,7 @@ fi log "Creating JKS from pem files" rm -f truststore.jks -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -importcert -alias mongoCACert -noprompt -file /tmp/mongo.crt -keystore /tmp/truststore.jks -storepass confluent +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -importcert -alias mongoCACert -noprompt -file /tmp/mongo.crt -keystore /tmp/truststore.jks -storepass confluent if [[ "$OSTYPE" == "darwin"* ]] then diff --git a/environment/mdc-kerberos/start.sh b/environment/mdc-kerberos/start.sh index fe26d9e1ca..895028f348 100755 --- a/environment/mdc-kerberos/start.sh +++ b/environment/mdc-kerberos/start.sh @@ -35,7 +35,7 @@ if ! version_gt $TAG_BASE "5.4.99"; then DISABLE_REPLICATOR_MONITORING="-f ../../environment/mdc-plaintext/docker-compose.no-replicator-monitoring.yml" else log "🎱 Installing replicator confluentinc/kafka-connect-replicator:$TAG for Replicator Monitoring" - docker run -u0 -i --rm -v ${DIR}/../../confluent-hub:/usr/share/confluent-hub-components ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "confluent-hub install --no-prompt confluentinc/kafka-connect-replicator:$TAG && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" + docker run -u0 -i --rm -v ${DIR}/../../confluent-hub:/usr/share/confluent-hub-components ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} bash -c "confluent-hub install --no-prompt confluentinc/kafka-connect-replicator:$TAG && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" fi docker compose -f ../../environment/mdc-plaintext/docker-compose.yml -f ../../environment/mdc-kerberos/docker-compose.kerberos.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} down -v --remove-orphans diff --git a/environment/mdc-plaintext/docker-compose.yml b/environment/mdc-plaintext/docker-compose.yml index 3ee2404ebf..5d80a84d38 100644 --- a/environment/mdc-plaintext/docker-compose.yml +++ b/environment/mdc-plaintext/docker-compose.yml @@ -107,7 +107,7 @@ services: KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 connect-us: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} hostname: connect-us container_name: connect-us ports: @@ -153,7 +153,7 @@ services: - ../../confluent-hub:/usr/share/confluent-hub-components connect-europe: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} hostname: connect-europe container_name: connect-europe ports: diff --git a/environment/mdc-plaintext/start.sh b/environment/mdc-plaintext/start.sh index 519f934370..e2990effec 100755 --- a/environment/mdc-plaintext/start.sh +++ b/environment/mdc-plaintext/start.sh @@ -48,7 +48,7 @@ if ! version_gt $TAG_BASE "5.4.99"; then DISABLE_REPLICATOR_MONITORING="-f ../../environment/mdc-plaintext/docker-compose.no-replicator-monitoring.yml" else log "🎱 Installing replicator confluentinc/kafka-connect-replicator:$TAG for Replicator Monitoring" - docker run -u0 -i --rm -v ${DIR}/../../confluent-hub:/usr/share/confluent-hub-components ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "confluent-hub install --no-prompt confluentinc/kafka-connect-replicator:$TAG && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" + docker run -u0 -i --rm -v ${DIR}/../../confluent-hub:/usr/share/confluent-hub-components ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} bash -c "confluent-hub install --no-prompt confluentinc/kafka-connect-replicator:$TAG && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" fi docker compose -f ../../environment/mdc-plaintext/docker-compose.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} build diff --git a/environment/mdc-sasl-plain/start.sh b/environment/mdc-sasl-plain/start.sh index 8d2583bad2..5e204e90f6 100755 --- a/environment/mdc-sasl-plain/start.sh +++ b/environment/mdc-sasl-plain/start.sh @@ -35,7 +35,7 @@ if ! version_gt $TAG_BASE "5.4.99"; then DISABLE_REPLICATOR_MONITORING="-f ../../environment/mdc-plaintext/docker-compose.no-replicator-monitoring.yml" else log "🎱 Installing replicator confluentinc/kafka-connect-replicator:$TAG for Replicator Monitoring" - docker run -u0 -i --rm -v ${DIR}/../../confluent-hub:/usr/share/confluent-hub-components ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "confluent-hub install --no-prompt confluentinc/kafka-connect-replicator:$TAG && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" + docker run -u0 -i --rm -v ${DIR}/../../confluent-hub:/usr/share/confluent-hub-components ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} bash -c "confluent-hub install --no-prompt confluentinc/kafka-connect-replicator:$TAG && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" fi docker compose -f ../../environment/mdc-plaintext/docker-compose.yml -f ../../environment/mdc-sasl-plain/docker-compose.sasl-plain.yml ${ENABLE_DOCKER_COMPOSE_FILE_OVERRIDE} ${DISABLE_REPLICATOR_MONITORING} build diff --git a/environment/plaintext/docker-compose.yml b/environment/plaintext/docker-compose.yml index b34fd00825..80adabfa6b 100644 --- a/environment/plaintext/docker-compose.yml +++ b/environment/plaintext/docker-compose.yml @@ -176,7 +176,7 @@ services: PYROSCOPE_SERVER_ADDRESS: "http://pyroscope:4040" connect: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} hostname: connect container_name: connect restart: always @@ -245,7 +245,7 @@ services: PYROSCOPE_SERVER_ADDRESS: "http://pyroscope:4040" connect2: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} hostname: connect2 container_name: connect2 restart: always @@ -317,7 +317,7 @@ services: PYROSCOPE_SERVER_ADDRESS: "http://pyroscope:4040" connect3: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} hostname: connect3 container_name: connect3 restart: always diff --git a/environment/rbac-sasl-plain/start.sh b/environment/rbac-sasl-plain/start.sh index 8e3a5dc02c..16946a4f87 100755 --- a/environment/rbac-sasl-plain/start.sh +++ b/environment/rbac-sasl-plain/start.sh @@ -48,9 +48,9 @@ docker run --quiet --rm -v $PWD:/tmp alpine/openssl x509 -req -in /tmp/server.cs log "LDAPS: Create a JKS truststore" rm -f ldap_truststore.jks # We import the test CA certificate -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/ca.crt -keystore /tmp/ldap_truststore.jks -storetype JKS -storepass 'welcome123' -noprompt +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -import -v -alias testroot -file /tmp/ca.crt -keystore /tmp/ldap_truststore.jks -storetype JKS -storepass 'welcome123' -noprompt log "LDAPS: Displaying truststore" -docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} keytool -list -keystore /tmp/ldap_truststore.jks -storepass 'welcome123' -v +docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} keytool -list -keystore /tmp/ldap_truststore.jks -storepass 'welcome123' -v cd - ../../environment/rbac-sasl-plain/stop.sh $@ diff --git a/operator/rbac/04-start-remaining-components.sh b/operator/rbac/04-start-remaining-components.sh index 73378354c6..3f10fb9186 100755 --- a/operator/rbac/04-start-remaining-components.sh +++ b/operator/rbac/04-start-remaining-components.sh @@ -317,8 +317,8 @@ grep "confluent.controlcenter.ui.autoupdate.enable" $C3_PSC_FILE > /dev/null if [[ $? -eq 1 ]]; then log "updating c3 yaml..." # use linux to run sed - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/confluent.controlcenter.data.dir/a \ confluent.controlcenter.ui.autoupdate.enable=false' /tmp/confluent-operator/helm/confluent-operator/charts/controlcenter/templates/controlcenter-psc.yaml - # docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/confluent.controlcenter.data.dir/a \ confluent.controlcenter.service.healthcheck.interval.sec=600' /tmp/confluent-operator/helm/confluent-operator/charts/controlcenter/templates/controlcenter-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/confluent.controlcenter.data.dir/a \ confluent.controlcenter.ui.autoupdate.enable=false' /tmp/confluent-operator/helm/confluent-operator/charts/controlcenter/templates/controlcenter-psc.yaml + # docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/confluent.controlcenter.data.dir/a \ confluent.controlcenter.service.healthcheck.interval.sec=600' /tmp/confluent-operator/helm/confluent-operator/charts/controlcenter/templates/controlcenter-psc.yaml fi # For operator 1.6.1 manually edit ksql psc to allow CORS. This might need to be tweaked as we upgrade versions KSQL_PSC_FILE="${DIR}/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml" @@ -326,27 +326,27 @@ grep "access.control.allow.origin" $KSQL_PSC_FILE > /dev/null if [[ $? -eq 1 ]]; then log "updating ksql yaml..." # use linux to run sed - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/authentication.skip.paths/a \ access.control.allow.origin=*' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/authentication.skip.paths/a \ access.control.allow.methods=GET,POST,HEAD' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/authentication.skip.paths/a \ access.control.allow.headers=X-Requested-With,Content-Type,Accept,Origin,Authorization' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.logger.processing=ERROR, kafka_appender' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender=org.apache.kafka.log4jappender.KafkaLog4jAppender' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.layout=io.confluent.common.logging.log4j.StructuredJsonLayout' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.BrokerList=kafka:9071' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.Topic={{ .Release.Namespace }}.{{ $.Values.name }}_ksql_processing_log' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.SyncSend=false' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.SecurityProtocol=SASL_SSL' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.SaslMechanism=PLAIN' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.ClientJaasConf=org.apache.kafka.common.security.plain.PlainLoginModule required username="kafka" password="kafka-secret";' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.SslKeystoreType=JKS' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.SslTruststoreLocation=/tmp/truststore.jks' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.SslTruststorePassword=mystorepassword' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/## ksql configuration/a \ ksql.logging.processing.rows.include=true' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/## ksql configuration/a \ ksql.logging.processing.stream.auto.create=true' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/## ksql configuration/a \ ksql.logging.processing.topic.auto.create=true' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml - docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} sed -i '/## ksql configuration/a \ ksql.logging.processing.topic.name={{ .Release.Namespace }}.{{ $.Values.name }}_ksql_processing_log' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/authentication.skip.paths/a \ access.control.allow.origin=*' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/authentication.skip.paths/a \ access.control.allow.methods=GET,POST,HEAD' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/authentication.skip.paths/a \ access.control.allow.headers=X-Requested-With,Content-Type,Accept,Origin,Authorization' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.logger.processing=ERROR, kafka_appender' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender=org.apache.kafka.log4jappender.KafkaLog4jAppender' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.layout=io.confluent.common.logging.log4j.StructuredJsonLayout' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.BrokerList=kafka:9071' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.Topic={{ .Release.Namespace }}.{{ $.Values.name }}_ksql_processing_log' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.SyncSend=false' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.SecurityProtocol=SASL_SSL' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.SaslMechanism=PLAIN' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.ClientJaasConf=org.apache.kafka.common.security.plain.PlainLoginModule required username="kafka" password="kafka-secret";' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.SslKeystoreType=JKS' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.SslTruststoreLocation=/tmp/truststore.jks' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/log4j.rootLogger=INFO, stdout/a \ log4j.appender.kafka_appender.SslTruststorePassword=mystorepassword' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/## ksql configuration/a \ ksql.logging.processing.rows.include=true' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/## ksql configuration/a \ ksql.logging.processing.stream.auto.create=true' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/## ksql configuration/a \ ksql.logging.processing.topic.auto.create=true' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml + docker run --quiet --rm -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} sed -i '/## ksql configuration/a \ ksql.logging.processing.topic.name={{ .Release.Namespace }}.{{ $.Values.name }}_ksql_processing_log' /tmp/confluent-operator/helm/confluent-operator/charts/ksql/templates/ksql-psc.yaml fi log "Deploy KSQL" diff --git a/other/monitoring-sink-latency/docker-compose.plaintext.yml b/other/monitoring-sink-latency/docker-compose.plaintext.yml index 33c80fe67b..3bd54c4066 100644 --- a/other/monitoring-sink-latency/docker-compose.plaintext.yml +++ b/other/monitoring-sink-latency/docker-compose.plaintext.yml @@ -28,7 +28,7 @@ services: connect-with-fetch-latency: cap_add: - NET_ADMIN - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} hostname: connect-with-fetch-latency container_name: connect-with-fetch-latency restart: always @@ -75,7 +75,7 @@ services: connect-with-put-latency: cap_add: - NET_ADMIN - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} hostname: connect-with-put-latency container_name: connect-with-put-latency restart: always diff --git a/reproduction-models b/reproduction-models index 519aee89c5..f6b6963431 160000 --- a/reproduction-models +++ b/reproduction-models @@ -1 +1 @@ -Subproject commit 519aee89c56daa9f26ce7c990b9b796a4ffde2e1 +Subproject commit f6b6963431f629a992e58b465068806d23450fb0 diff --git a/scripts/cli/playground b/scripts/cli/playground index cdd7bc56d3..e6e6c20bee 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8590,9 +8590,9 @@ function maybe_create_image() return fi set +e - log "🧰 Checking if Docker image ${CP_CONNECT_IMAGE}:${CONNECT_TAG} contains additional tools" + log "🧰 Checking if Docker image ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} contains additional tools" log "⏳ it can take a while if image is downloaded for the first time" - docker run --quiet --rm ${CP_CONNECT_IMAGE}:${CONNECT_TAG} type unzip > /dev/null 2>&1 + docker run --quiet --rm ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} type unzip > /dev/null 2>&1 if [ $? != 0 ] then if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" @@ -8617,13 +8617,13 @@ else log "🐛📂 not deleting tmp dir $tmp_dir" fi cat << EOF > $tmp_dir/Dockerfile -FROM ${CP_CONNECT_IMAGE}:${CONNECT_TAG} +FROM ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} USER root RUN ${CONNECT_3RDPARTY_INSTALL} USER ${CONNECT_USER} EOF - log "👷📦 Re-building Docker image ${CP_CONNECT_IMAGE}:${CONNECT_TAG} to include additional tools" - docker build -t ${CP_CONNECT_IMAGE}:${CONNECT_TAG} $tmp_dir + log "👷📦 Re-building Docker image ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} to include additional tools" + docker build -t ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} $tmp_dir rm -rf $tmp_dir fi set -e @@ -9057,18 +9057,18 @@ function timeout() { function get_connect_image() { set +e - CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) + CP_CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) set -e - if [ "$CONNECT_TAG" == "" ] + if [ "$CP_CONNECT_TAG" == "" ] then if [ -z "$TAG" ] then - CONNECT_TAG=$(grep "export TAG" $root_folder/scripts/utils.sh | head -1 | cut -d "=" -f 2 | cut -d " " -f 1) + CP_CONNECT_TAG=$(grep "export TAG" $root_folder/scripts/utils.sh | head -1 | cut -d "=" -f 2 | cut -d " " -f 1) else - CONNECT_TAG=$TAG + CP_CONNECT_TAG=$TAG fi - if [ "$CONNECT_TAG" == "" ] + if [ "$CP_CONNECT_TAG" == "" ] then logerror "Error while getting default TAG in get_connect_image()" exit 1 @@ -9077,7 +9077,7 @@ function get_connect_image() { if [ -z "$CP_CONNECT_IMAGE" ] then - if version_gt $CONNECT_TAG 5.2.99 + if version_gt $CP_CONNECT_TAG 5.2.99 then CP_CONNECT_IMAGE=confluentinc/cp-server-connect-base else @@ -18132,7 +18132,7 @@ playground_get_docker_compose_command() { # src/commands/get-docker-compose.sh # keep TAG, CONNECT TAG and ORACLE_IMAGE export TAG=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d ":" -f 2) - export CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) + export CP_CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) export ORACLE_IMAGE=$(docker inspect -f '{{.Config.Image}}' oracle 2> /dev/null) handle_aws_credentials @@ -18912,7 +18912,7 @@ playground_tcp_proxy_start_command() { # keep TAG, CONNECT TAG and ORACLE_IMAGE export TAG=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d ":" -f 2) - export CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) + export CP_CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) export ORACLE_IMAGE=$(docker inspect -f '{{.Config.Image}}' oracle 2> /dev/null) docker_command=$(playground state get run.docker_command) @@ -19417,7 +19417,7 @@ playground_tools_certs_create_command() { get_connect_image new_open_ssl=0 - if version_gt $CONNECT_TAG "7.7.99" + if version_gt $CP_CONNECT_TAG "7.7.99" then new_open_ssl=1 fi @@ -19425,7 +19425,7 @@ playground_tools_certs_create_command() { cd "${output_folder}" cp $root_folder/scripts/cli/src/ssl/certs-create.sh . log "🔐 Generate keys and certificates in folder ${output_folder}" - docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" + docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" } # :command.function @@ -19996,9 +19996,9 @@ playground_container_recreate_command() { if [[ ! -n "$ignore_current_versions" ]] then - # keep TAG and CONNECT_TAG + # keep TAG and CP_CONNECT_TAG export TAG=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d ":" -f 2) - export CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) + export CP_CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) fi export ORACLE_IMAGE=$(docker inspect -f '{{.Config.Image}}' oracle 2> /dev/null) @@ -20212,7 +20212,7 @@ playground_container_set_environment_variables_command() { # keep TAG, CONNECT TAG and ORACLE_IMAGE export TAG=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d ":" -f 2) - export CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) + export CP_CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) export ORACLE_IMAGE=$(docker inspect -f '{{.Config.Image}}' oracle 2> /dev/null) docker_command=$(playground state get run.docker_command) @@ -20484,7 +20484,7 @@ playground_topic_describe_command() { echo "kafka-topics --describe --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties" fi get_connect_image - docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-topics --describe --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties + docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-topics --describe --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties else if [[ -n "$verbose" ]] then @@ -20854,7 +20854,7 @@ playground_topic_consume_command() { if [[ "$environment" == "ccloud" ]] then get_connect_image - docker run -i --rm -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/etc/kafka/tools-log4j.properties" -e value_type=$value_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} $nottailing2 kafka-$value_type-console-consumer --bootstrap-server $BOOTSTRAP_SERVERS --topic $topic --consumer-property ssl.endpoint.identification.algorithm=https --consumer-property sasl.mechanism=PLAIN --consumer-property security.protocol=SASL_SSL --consumer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --property print.schema.ids=true --property schema.id.separator="|" --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" --skip-message-on-error $security $nottailing1 > "$fifo_path" 2>&1 & + docker run -i --rm -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/etc/kafka/tools-log4j.properties" -e value_type=$value_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} $nottailing2 kafka-$value_type-console-consumer --bootstrap-server $BOOTSTRAP_SERVERS --topic $topic --consumer-property ssl.endpoint.identification.algorithm=https --consumer-property sasl.mechanism=PLAIN --consumer-property security.protocol=SASL_SSL --consumer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --property print.schema.ids=true --property schema.id.separator="|" --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" --skip-message-on-error $security $nottailing1 > "$fifo_path" 2>&1 & else docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/etc/kafka/tools-log4j.properties" $container $nottailing2 kafka-$value_type-console-consumer -bootstrap-server $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic --property print.schema.ids=true --property schema.id.separator="|" --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" --skip-message-on-error $security $nottailing1 > "$fifo_path" 2>&1 & fi @@ -20862,7 +20862,7 @@ playground_topic_consume_command() { if [[ "$environment" == "ccloud" ]] then get_connect_image - docker run -i --rm -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/etc/kafka/tools-log4j.properties" -e value_type=$value_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} $nottailing2 kafka-$value_type-console-consumer --bootstrap-server $BOOTSTRAP_SERVERS --topic $topic --consumer-property ssl.endpoint.identification.algorithm=https --consumer-property sasl.mechanism=PLAIN --consumer-property security.protocol=SASL_SSL --consumer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --property print.schema.ids=true --property schema.id.separator="|" --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" --property key.deserializer=org.apache.kafka.common.serialization.StringDeserializer --skip-message-on-error $security $nottailing1 > "$fifo_path" 2>&1 & + docker run -i --rm -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/etc/kafka/tools-log4j.properties" -e value_type=$value_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} $nottailing2 kafka-$value_type-console-consumer --bootstrap-server $BOOTSTRAP_SERVERS --topic $topic --consumer-property ssl.endpoint.identification.algorithm=https --consumer-property sasl.mechanism=PLAIN --consumer-property security.protocol=SASL_SSL --consumer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --property print.schema.ids=true --property schema.id.separator="|" --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" --property key.deserializer=org.apache.kafka.common.serialization.StringDeserializer --skip-message-on-error $security $nottailing1 > "$fifo_path" 2>&1 & else docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/etc/kafka/tools-log4j.properties" $container $nottailing2 kafka-$value_type-console-consumer --bootstrap-server $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic --property print.partition=true --property print.schema.ids=true --property schema.id.separator="|" --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" --property key.deserializer=org.apache.kafka.common.serialization.StringDeserializer --skip-message-on-error $security $nottailing1 > "$fifo_path" 2>&1 & fi @@ -20872,7 +20872,7 @@ playground_topic_consume_command() { if [[ "$environment" == "ccloud" ]] then get_connect_image - docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} $nottailing2 kafka-console-consumer --bootstrap-server $BOOTSTRAP_SERVERS --topic $topic --consumer.config /tmp/configuration/ccloud.properties --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" $security $nottailing1 > "$fifo_path" 2>&1 & + docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} $nottailing2 kafka-console-consumer --bootstrap-server $BOOTSTRAP_SERVERS --topic $topic --consumer.config /tmp/configuration/ccloud.properties --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" $security $nottailing1 > "$fifo_path" 2>&1 & else docker exec $container $nottailing2 kafka-console-consumer --bootstrap-server $bootstrap_server --topic $topic --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" $security $nottailing1 > "$fifo_path" 2>&1 & fi @@ -21213,7 +21213,7 @@ playground_topic_produce_command() { exit 1 fi get_connect_image - if ! version_gt $CONNECT_TAG "7.1.99" + if ! version_gt $CP_CONNECT_TAG "7.1.99" then logerror "❌ --tombstone is set but it can be produced only with CP 7.2+" exit 1 @@ -21227,7 +21227,7 @@ playground_topic_produce_command() { if [[ -n "$headers" ]] then get_connect_image - if ! version_gt $CONNECT_TAG "7.1.99" + if ! version_gt $CP_CONNECT_TAG "7.1.99" then logerror "❌ --headers is set but it can be produced only with CP 7.2+" exit 1 @@ -22079,17 +22079,17 @@ playground_topic_produce_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\" " + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\" " fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" fi else @@ -22099,17 +22099,17 @@ playground_topic_produce_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone fi fi else @@ -22197,17 +22197,17 @@ playground_topic_produce_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi else if [ "$key_schema_type" = "avro" ] || [ "$key_schema_type" = "protobuf" ] || [ "$key_schema_type" = "json-schema" ] @@ -22216,18 +22216,18 @@ playground_topic_produce_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi fi else @@ -22237,17 +22237,17 @@ playground_topic_produce_command() { if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi fi else @@ -22388,7 +22388,7 @@ playground_topic_create_command() { echo "kafka-topics --create --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties --partitions $nb_partitions ${other_args[*]}" fi get_connect_image - docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-topics --create --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties --partitions $nb_partitions ${other_args[*]} + docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-topics --create --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties --partitions $nb_partitions ${other_args[*]} else if [[ -n "$verbose" ]] then @@ -22448,7 +22448,7 @@ playground_topic_delete_command() { echo "kafka-topics --delete --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties" fi get_connect_image - docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-topics --delete --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties + docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-topics --delete --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties else if [[ -n "$verbose" ]] then @@ -22518,7 +22518,7 @@ playground_topic_alter_command() { fi get_connect_image - docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-configs --alter --entity-type topics --entity-name $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties ${other_args[*]} + docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-configs --alter --entity-type topics --entity-name $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties ${other_args[*]} else docker exec $container kafka-configs --alter --entity-type topics --entity-name $topic --bootstrap-server $bootstrap_server:9092 $security ${other_args[*]} fi @@ -22561,7 +22561,7 @@ playground_connector_plugin_search_jar_command() { get_connect_image log "🔌 Downloading connector plugin $connector_plugin:$connector_tag" - docker run -u0 -i --rm -v $tmp_dir:/usr/share/confluent-hub-components ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "confluent-hub install --no-prompt $connector_plugin:$connector_tag && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" | grep "Downloading" + docker run -u0 -i --rm -v $tmp_dir:/usr/share/confluent-hub-components ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} bash -c "confluent-hub install --no-prompt $connector_plugin:$connector_tag && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" | grep "Downloading" log "🤎 Listing jar files" cd $tmp_dir/*/lib @@ -24052,7 +24052,7 @@ playground_connector_show_lag_command() { else consumer_group="connect-$connector" fi - docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SASL_JAAS_CONFIG="$SASL_JAAS_CONFIG" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-consumer-groups --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties --group $consumer_group --describe | grep -v PARTITION | sed '/^$/d' &> $lag_output + docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SASL_JAAS_CONFIG="$SASL_JAAS_CONFIG" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-consumer-groups --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties --group $consumer_group --describe | grep -v PARTITION | sed '/^$/d' &> $lag_output else docker exec $container kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector --describe $security | grep -v PARTITION | sed '/^$/d' &> $lag_output fi diff --git a/scripts/cli/src/commands/connector-plugin/search-jar.sh b/scripts/cli/src/commands/connector-plugin/search-jar.sh index bf4358093c..8ba6aea2ec 100644 --- a/scripts/cli/src/commands/connector-plugin/search-jar.sh +++ b/scripts/cli/src/commands/connector-plugin/search-jar.sh @@ -28,7 +28,7 @@ fi get_connect_image log "🔌 Downloading connector plugin $connector_plugin:$connector_tag" -docker run -u0 -i --rm -v $tmp_dir:/usr/share/confluent-hub-components ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "confluent-hub install --no-prompt $connector_plugin:$connector_tag && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" | grep "Downloading" +docker run -u0 -i --rm -v $tmp_dir:/usr/share/confluent-hub-components ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} bash -c "confluent-hub install --no-prompt $connector_plugin:$connector_tag && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" | grep "Downloading" log "🤎 Listing jar files" cd $tmp_dir/*/lib diff --git a/scripts/cli/src/commands/connector/show-lag.sh b/scripts/cli/src/commands/connector/show-lag.sh index 7d150cc5ec..9567c72b66 100644 --- a/scripts/cli/src/commands/connector/show-lag.sh +++ b/scripts/cli/src/commands/connector/show-lag.sh @@ -217,7 +217,7 @@ do else consumer_group="connect-$connector" fi - docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SASL_JAAS_CONFIG="$SASL_JAAS_CONFIG" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-consumer-groups --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties --group $consumer_group --describe | grep -v PARTITION | sed '/^$/d' &> $lag_output + docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SASL_JAAS_CONFIG="$SASL_JAAS_CONFIG" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-consumer-groups --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties --group $consumer_group --describe | grep -v PARTITION | sed '/^$/d' &> $lag_output else docker exec $container kafka-consumer-groups --bootstrap-server $bootstrap_server:9092 --group connect-$connector --describe $security | grep -v PARTITION | sed '/^$/d' &> $lag_output fi diff --git a/scripts/cli/src/commands/container/recreate.sh b/scripts/cli/src/commands/container/recreate.sh index ca36af1b17..f6b9b073db 100644 --- a/scripts/cli/src/commands/container/recreate.sh +++ b/scripts/cli/src/commands/container/recreate.sh @@ -4,9 +4,9 @@ export IGNORE_CHECK_FOR_DOCKER_COMPOSE=true if [[ ! -n "$ignore_current_versions" ]] then - # keep TAG and CONNECT_TAG + # keep TAG and CP_CONNECT_TAG export TAG=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d ":" -f 2) - export CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) + export CP_CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) fi export ORACLE_IMAGE=$(docker inspect -f '{{.Config.Image}}' oracle 2> /dev/null) diff --git a/scripts/cli/src/commands/container/set-environment-variables.sh b/scripts/cli/src/commands/container/set-environment-variables.sh index 1cc4537c33..fb8e832451 100644 --- a/scripts/cli/src/commands/container/set-environment-variables.sh +++ b/scripts/cli/src/commands/container/set-environment-variables.sh @@ -22,7 +22,7 @@ fi # keep TAG, CONNECT TAG and ORACLE_IMAGE export TAG=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d ":" -f 2) -export CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) +export CP_CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) export ORACLE_IMAGE=$(docker inspect -f '{{.Config.Image}}' oracle 2> /dev/null) docker_command=$(playground state get run.docker_command) diff --git a/scripts/cli/src/commands/get-docker-compose.sh b/scripts/cli/src/commands/get-docker-compose.sh index 73041741a4..3a13726a94 100644 --- a/scripts/cli/src/commands/get-docker-compose.sh +++ b/scripts/cli/src/commands/get-docker-compose.sh @@ -1,6 +1,6 @@ # keep TAG, CONNECT TAG and ORACLE_IMAGE export TAG=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d ":" -f 2) -export CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) +export CP_CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) export ORACLE_IMAGE=$(docker inspect -f '{{.Config.Image}}' oracle 2> /dev/null) handle_aws_credentials diff --git a/scripts/cli/src/commands/tcp-proxy/start.sh b/scripts/cli/src/commands/tcp-proxy/start.sh index 4e061ed728..fb8904eca8 100644 --- a/scripts/cli/src/commands/tcp-proxy/start.sh +++ b/scripts/cli/src/commands/tcp-proxy/start.sh @@ -8,7 +8,7 @@ skip_automatic_connector_config=${args[--skip-automatic-connector-config]} # keep TAG, CONNECT TAG and ORACLE_IMAGE export TAG=$(docker inspect -f '{{.Config.Image}}' broker 2> /dev/null | cut -d ":" -f 2) -export CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) +export CP_CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) export ORACLE_IMAGE=$(docker inspect -f '{{.Config.Image}}' oracle 2> /dev/null) docker_command=$(playground state get run.docker_command) diff --git a/scripts/cli/src/commands/tools/certs-create.sh b/scripts/cli/src/commands/tools/certs-create.sh index 6bee9114ea..14ff5ba8dc 100644 --- a/scripts/cli/src/commands/tools/certs-create.sh +++ b/scripts/cli/src/commands/tools/certs-create.sh @@ -19,7 +19,7 @@ container_list="${containers[*]}" get_connect_image new_open_ssl=0 -if version_gt $CONNECT_TAG "7.7.99" +if version_gt $CP_CONNECT_TAG "7.7.99" then new_open_ssl=1 fi @@ -27,4 +27,4 @@ mkdir -p "${output_folder}" cd "${output_folder}" cp $root_folder/scripts/cli/src/ssl/certs-create.sh . log "🔐 Generate keys and certificates in folder ${output_folder}" - docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" \ No newline at end of file + docker run -u0 --rm -v $root_folder/scripts/cli/src/openssl.cnf:/usr/local/ssl/openssl.cnf -v $PWD:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} bash -c "/tmp/certs-create.sh $maybe_redirect_output \"$container_list\" $new_open_ssl && chown -R $(id -u $USER):$(id -g $USER) /tmp/" \ No newline at end of file diff --git a/scripts/cli/src/commands/topic/alter.sh b/scripts/cli/src/commands/topic/alter.sh index 61eb862737..12e72a8fe9 100644 --- a/scripts/cli/src/commands/topic/alter.sh +++ b/scripts/cli/src/commands/topic/alter.sh @@ -33,7 +33,7 @@ else fi get_connect_image - docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-configs --alter --entity-type topics --entity-name $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties ${other_args[*]} + docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-configs --alter --entity-type topics --entity-name $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties ${other_args[*]} else docker exec $container kafka-configs --alter --entity-type topics --entity-name $topic --bootstrap-server $bootstrap_server:9092 $security ${other_args[*]} fi diff --git a/scripts/cli/src/commands/topic/consume.sh b/scripts/cli/src/commands/topic/consume.sh index 1372b7c9a9..2362b298e5 100644 --- a/scripts/cli/src/commands/topic/consume.sh +++ b/scripts/cli/src/commands/topic/consume.sh @@ -314,7 +314,7 @@ fi if [[ "$environment" == "ccloud" ]] then get_connect_image - docker run -i --rm -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/etc/kafka/tools-log4j.properties" -e value_type=$value_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} $nottailing2 kafka-$value_type-console-consumer --bootstrap-server $BOOTSTRAP_SERVERS --topic $topic --consumer-property ssl.endpoint.identification.algorithm=https --consumer-property sasl.mechanism=PLAIN --consumer-property security.protocol=SASL_SSL --consumer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --property print.schema.ids=true --property schema.id.separator="|" --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" --skip-message-on-error $security $nottailing1 > "$fifo_path" 2>&1 & + docker run -i --rm -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/etc/kafka/tools-log4j.properties" -e value_type=$value_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} $nottailing2 kafka-$value_type-console-consumer --bootstrap-server $BOOTSTRAP_SERVERS --topic $topic --consumer-property ssl.endpoint.identification.algorithm=https --consumer-property sasl.mechanism=PLAIN --consumer-property security.protocol=SASL_SSL --consumer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --property print.schema.ids=true --property schema.id.separator="|" --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" --skip-message-on-error $security $nottailing1 > "$fifo_path" 2>&1 & else docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/etc/kafka/tools-log4j.properties" $container $nottailing2 kafka-$value_type-console-consumer -bootstrap-server $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic --property print.schema.ids=true --property schema.id.separator="|" --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" --skip-message-on-error $security $nottailing1 > "$fifo_path" 2>&1 & fi @@ -322,7 +322,7 @@ fi if [[ "$environment" == "ccloud" ]] then get_connect_image - docker run -i --rm -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/etc/kafka/tools-log4j.properties" -e value_type=$value_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} $nottailing2 kafka-$value_type-console-consumer --bootstrap-server $BOOTSTRAP_SERVERS --topic $topic --consumer-property ssl.endpoint.identification.algorithm=https --consumer-property sasl.mechanism=PLAIN --consumer-property security.protocol=SASL_SSL --consumer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --property print.schema.ids=true --property schema.id.separator="|" --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" --property key.deserializer=org.apache.kafka.common.serialization.StringDeserializer --skip-message-on-error $security $nottailing1 > "$fifo_path" 2>&1 & + docker run -i --rm -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/etc/kafka/tools-log4j.properties" -e value_type=$value_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} $nottailing2 kafka-$value_type-console-consumer --bootstrap-server $BOOTSTRAP_SERVERS --topic $topic --consumer-property ssl.endpoint.identification.algorithm=https --consumer-property sasl.mechanism=PLAIN --consumer-property security.protocol=SASL_SSL --consumer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --property print.schema.ids=true --property schema.id.separator="|" --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" --property key.deserializer=org.apache.kafka.common.serialization.StringDeserializer --skip-message-on-error $security $nottailing1 > "$fifo_path" 2>&1 & else docker exec -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/etc/kafka/tools-log4j.properties" $container $nottailing2 kafka-$value_type-console-consumer --bootstrap-server $bootstrap_server --property schema.registry.url=$sr_url_cli --topic $topic --property print.partition=true --property print.schema.ids=true --property schema.id.separator="|" --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" --property key.deserializer=org.apache.kafka.common.serialization.StringDeserializer --skip-message-on-error $security $nottailing1 > "$fifo_path" 2>&1 & fi @@ -332,7 +332,7 @@ fi if [[ "$environment" == "ccloud" ]] then get_connect_image - docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} $nottailing2 kafka-console-consumer --bootstrap-server $BOOTSTRAP_SERVERS --topic $topic --consumer.config /tmp/configuration/ccloud.properties --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" $security $nottailing1 > "$fifo_path" 2>&1 & + docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} $nottailing2 kafka-console-consumer --bootstrap-server $BOOTSTRAP_SERVERS --topic $topic --consumer.config /tmp/configuration/ccloud.properties --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" $security $nottailing1 > "$fifo_path" 2>&1 & else docker exec $container $nottailing2 kafka-console-consumer --bootstrap-server $bootstrap_server --topic $topic --property print.partition=true --property print.offset=true --property print.headers=true --property headers.separator=, --property headers.deserializer=org.apache.kafka.common.serialization.StringDeserializer --property print.timestamp=true --property print.key=true --property key.separator="|" $security $nottailing1 > "$fifo_path" 2>&1 & fi diff --git a/scripts/cli/src/commands/topic/create.sh b/scripts/cli/src/commands/topic/create.sh index 96fda6e2a0..037f9fd69c 100644 --- a/scripts/cli/src/commands/topic/create.sh +++ b/scripts/cli/src/commands/topic/create.sh @@ -35,7 +35,7 @@ then echo "kafka-topics --create --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties --partitions $nb_partitions ${other_args[*]}" fi get_connect_image - docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-topics --create --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties --partitions $nb_partitions ${other_args[*]} + docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-topics --create --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties --partitions $nb_partitions ${other_args[*]} else if [[ -n "$verbose" ]] then diff --git a/scripts/cli/src/commands/topic/delete.sh b/scripts/cli/src/commands/topic/delete.sh index c3a4393fc0..3a197aad4a 100644 --- a/scripts/cli/src/commands/topic/delete.sh +++ b/scripts/cli/src/commands/topic/delete.sh @@ -39,7 +39,7 @@ then echo "kafka-topics --delete --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties" fi get_connect_image - docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-topics --delete --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties + docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-topics --delete --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties else if [[ -n "$verbose" ]] then diff --git a/scripts/cli/src/commands/topic/describe.sh b/scripts/cli/src/commands/topic/describe.sh index 09701205e9..f6b67425fa 100644 --- a/scripts/cli/src/commands/topic/describe.sh +++ b/scripts/cli/src/commands/topic/describe.sh @@ -43,7 +43,7 @@ do echo "kafka-topics --describe --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties" fi get_connect_image - docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-topics --describe --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties + docker run --quiet --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-topics --describe --topic $topic --bootstrap-server $BOOTSTRAP_SERVERS --command-config /tmp/configuration/ccloud.properties else if [[ -n "$verbose" ]] then diff --git a/scripts/cli/src/commands/topic/produce.sh b/scripts/cli/src/commands/topic/produce.sh index e2f6c7d076..c2ccc44d7d 100644 --- a/scripts/cli/src/commands/topic/produce.sh +++ b/scripts/cli/src/commands/topic/produce.sh @@ -143,7 +143,7 @@ then exit 1 fi get_connect_image - if ! version_gt $CONNECT_TAG "7.1.99" + if ! version_gt $CP_CONNECT_TAG "7.1.99" then logerror "❌ --tombstone is set but it can be produced only with CP 7.2+" exit 1 @@ -157,7 +157,7 @@ fi if [[ -n "$headers" ]] then get_connect_image - if ! version_gt $CONNECT_TAG "7.1.99" + if ! version_gt $CP_CONNECT_TAG "7.1.99" then logerror "❌ --headers is set but it can be produced only with CP 7.2+" exit 1 @@ -1002,17 +1002,17 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\" " + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator=\"|\" " fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.key=true --property key.separator="|" fi else if [[ -n "$headers" ]] @@ -1021,17 +1021,17 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\"" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v $KAFKA_DOCKER_PLAYGROUND_DIR/.ccloud/ak-tools-ccloud.delta:/tmp/configuration/ccloud.properties -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-console-producer --broker-list $BOOTSTRAP_SERVERS --topic $topic --producer.config /tmp/configuration/ccloud.properties $security $producer_properties $compression $tombstone fi fi else @@ -1119,17 +1119,17 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi else if [ "$key_schema_type" = "avro" ] || [ "$key_schema_type" = "protobuf" ] || [ "$key_schema_type" = "json-schema" ] @@ -1138,17 +1138,17 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.schema.file=\"/tmp/key_schema_file\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e key_schema_type=$key_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$key_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.schema.file="/tmp/key_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.key=true --property key.separator=\"|\" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.key=true --property key.separator="|" --property key.serializer=org.apache.kafka.common.serialization.StringSerializer $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi fi else @@ -1158,17 +1158,17 @@ do if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file --property parse.headers=true --property headers.delimiter=\"|\" --property headers.separator=\",\" --property headers.key.separator=\":\" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" --property parse.headers=true --property headers.delimiter="|" --property headers.separator="," --property headers.key.separator=":" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone else get_connect_image if [[ -n "$verbose" ]] then log "🐞 CLI command used to produce data" - echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" + echo "cat /tmp/verbose_input_file.txt | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS=\"-Dlog4j.configuration=file:/tmp/tools-log4j.properties\" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS=\"$BOOTSTRAP_SERVERS\" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" -e SCHEMA_REGISTRY_URL=\"$SCHEMA_REGISTRY_URL\" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config=\"$SASL_JAAS_CONFIG\" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info=\"$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO\" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file=/tmp/value_schema_file $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone" fi - head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone + head -n $nb_messages_to_send $output_final_file | awk -v counter=1 '{gsub("%g", counter); counter++; print}' | docker run -i --rm -v /tmp:/tmp -e SCHEMA_REGISTRY_LOG4J_OPTS="-Dlog4j.configuration=file:/tmp/tools-log4j.properties" -e value_schema_type=$value_schema_type -e BOOTSTRAP_SERVERS="$BOOTSTRAP_SERVERS" -e SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" -e SCHEMA_REGISTRY_URL="$SCHEMA_REGISTRY_URL" ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} kafka-$value_schema_type-console-producer --broker-list $BOOTSTRAP_SERVERS --producer-property ssl.endpoint.identification.algorithm=https --producer-property sasl.mechanism=PLAIN --producer-property security.protocol=SASL_SSL --producer-property sasl.jaas.config="$SASL_JAAS_CONFIG" --property basic.auth.credentials.source=USER_INFO --property schema.registry.basic.auth.user.info="$SCHEMA_REGISTRY_BASIC_AUTH_USER_INFO" --property schema.registry.url=$SCHEMA_REGISTRY_URL --topic $topic $security --property value.schema.file="/tmp/value_schema_file" $force_schema_id $key_subject_name_strategy_property $value_subject_name_strategy_property $avro_use_logical_type_converters_property $producer_properties $compression $tombstone fi fi else diff --git a/scripts/cli/src/lib/utils_function.sh b/scripts/cli/src/lib/utils_function.sh index 95cf0f0555..47d4641d19 100644 --- a/scripts/cli/src/lib/utils_function.sh +++ b/scripts/cli/src/lib/utils_function.sh @@ -254,9 +254,9 @@ function maybe_create_image() return fi set +e - log "🧰 Checking if Docker image ${CP_CONNECT_IMAGE}:${CONNECT_TAG} contains additional tools" + log "🧰 Checking if Docker image ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} contains additional tools" log "⏳ it can take a while if image is downloaded for the first time" - docker run --quiet --rm ${CP_CONNECT_IMAGE}:${CONNECT_TAG} type unzip > /dev/null 2>&1 + docker run --quiet --rm ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} type unzip > /dev/null 2>&1 if [ $? != 0 ] then if [[ "$TAG" == *ubi8 ]] || version_gt $TAG_BASE "5.9.0" @@ -281,13 +281,13 @@ else log "🐛📂 not deleting tmp dir $tmp_dir" fi cat << EOF > $tmp_dir/Dockerfile -FROM ${CP_CONNECT_IMAGE}:${CONNECT_TAG} +FROM ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} USER root RUN ${CONNECT_3RDPARTY_INSTALL} USER ${CONNECT_USER} EOF - log "👷📦 Re-building Docker image ${CP_CONNECT_IMAGE}:${CONNECT_TAG} to include additional tools" - docker build -t ${CP_CONNECT_IMAGE}:${CONNECT_TAG} $tmp_dir + log "👷📦 Re-building Docker image ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} to include additional tools" + docker build -t ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} $tmp_dir rm -rf $tmp_dir fi set -e @@ -721,18 +721,18 @@ function timeout() { function get_connect_image() { set +e - CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) + CP_CONNECT_TAG=$(docker inspect -f '{{.Config.Image}}' connect 2> /dev/null | cut -d ":" -f 2) set -e - if [ "$CONNECT_TAG" == "" ] + if [ "$CP_CONNECT_TAG" == "" ] then if [ -z "$TAG" ] then - CONNECT_TAG=$(grep "export TAG" $root_folder/scripts/utils.sh | head -1 | cut -d "=" -f 2 | cut -d " " -f 1) + CP_CONNECT_TAG=$(grep "export TAG" $root_folder/scripts/utils.sh | head -1 | cut -d "=" -f 2 | cut -d " " -f 1) else - CONNECT_TAG=$TAG + CP_CONNECT_TAG=$TAG fi - if [ "$CONNECT_TAG" == "" ] + if [ "$CP_CONNECT_TAG" == "" ] then logerror "Error while getting default TAG in get_connect_image()" exit 1 @@ -741,7 +741,7 @@ function get_connect_image() { if [ -z "$CP_CONNECT_IMAGE" ] then - if version_gt $CONNECT_TAG 5.2.99 + if version_gt $CP_CONNECT_TAG 5.2.99 then CP_CONNECT_IMAGE=confluentinc/cp-server-connect-base else diff --git a/scripts/utils.sh b/scripts/utils.sh index 1e0afbdd96..e639d2f6a5 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -241,16 +241,16 @@ then if [[ $0 == *"environment"* ]] then # log "DEBUG: start.sh from environment folder. Skipping..." - if [ -z "$CONNECT_TAG" ] + if [ -z "$CP_CONNECT_TAG" ] then - export CONNECT_TAG="$TAG" + export CP_CONNECT_TAG="$TAG" fi : elif [[ $0 == *"stop.sh"* ]] then - if [ -z "$CONNECT_TAG" ] + if [ -z "$CP_CONNECT_TAG" ] then - export CONNECT_TAG="$TAG" + export CP_CONNECT_TAG="$TAG" fi : elif [[ $0 == *"run-tests"* ]] @@ -276,9 +276,9 @@ then if [ "$connector_paths" == "" ] then # not a connector test - if [ -z "$CONNECT_TAG" ] + if [ -z "$CP_CONNECT_TAG" ] then - export CONNECT_TAG="$TAG" + export CP_CONNECT_TAG="$TAG" fi else ### @@ -299,7 +299,7 @@ then logwarn "CONNECTOR_TAG (--connector-tag option) was not set for element $i, setting it to latest" CONNECTOR_VERSION="latest" fi - export CONNECT_TAG="$TAG" + export CP_CONNECT_TAG="$TAG" maybe_create_image @@ -316,7 +316,7 @@ then fi log "🎱 Installing connector $owner/$name:$CONNECTOR_VERSION" set +e - docker run -u0 -i --rm -v ${DIR_UTILS}/../confluent-hub:/usr/share/confluent-hub-components ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "confluent-hub install --no-prompt $owner/$name:$CONNECTOR_VERSION && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" > /tmp/result.log 2>&1 + docker run -u0 -i --rm -v ${DIR_UTILS}/../confluent-hub:/usr/share/confluent-hub-components ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} bash -c "confluent-hub install --no-prompt $owner/$name:$CONNECTOR_VERSION && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" > /tmp/result.log 2>&1 if [ $? != 0 ] then logerror "❌ failed to install connector $owner/$name:$CONNECTOR_VERSION" @@ -377,9 +377,9 @@ then logerror "🎓 Check the related documentation https://kafka-docker-playground.io/#/how-it-works?id=🐳-docker-override" exit 1 else - if [ -z "$CONNECT_TAG" ] + if [ -z "$CP_CONNECT_TAG" ] then - export CONNECT_TAG="$TAG" + export CP_CONNECT_TAG="$TAG" fi fi fi @@ -390,16 +390,16 @@ else ### if [[ $0 == *"environment"* ]] then - if [ -z "$CONNECT_TAG" ] + if [ -z "$CP_CONNECT_TAG" ] then - export CONNECT_TAG="$TAG" + export CP_CONNECT_TAG="$TAG" fi : elif [[ $0 == *"stop.sh"* ]] then - if [ -z "$CONNECT_TAG" ] + if [ -z "$CP_CONNECT_TAG" ] then - export CONNECT_TAG="$TAG" + export CP_CONNECT_TAG="$TAG" fi CONNECTOR_TAG=$version : @@ -421,9 +421,9 @@ else if [ "$connector_paths" == "" ] then # not a connector test - if [ -z "$CONNECT_TAG" ] + if [ -z "$CP_CONNECT_TAG" ] then - export CONNECT_TAG="$TAG" + export CP_CONNECT_TAG="$TAG" maybe_create_image fi else @@ -449,15 +449,15 @@ else if [ "$name" == "" ] then # can happen for filestream - if [ -z "$CONNECT_TAG" ] + if [ -z "$CP_CONNECT_TAG" ] then - export CONNECT_TAG="$TAG" + export CP_CONNECT_TAG="$TAG" maybe_create_image fi else - if [ -z "$CONNECT_TAG" ] + if [ -z "$CP_CONNECT_TAG" ] then - export CONNECT_TAG="$TAG" + export CP_CONNECT_TAG="$TAG" fi ### @@ -478,7 +478,7 @@ else log "🎱 Installing connector from zip $connector_zip_name" set +e - docker run -u0 -i --rm -v ${DIR_UTILS}/../confluent-hub:/usr/share/confluent-hub-components -v /tmp:/tmp ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "confluent-hub install --no-prompt /tmp/${connector_zip_name} && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" > /tmp/result.log 2>&1 + docker run -u0 -i --rm -v ${DIR_UTILS}/../confluent-hub:/usr/share/confluent-hub-components -v /tmp:/tmp ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} bash -c "confluent-hub install --no-prompt /tmp/${connector_zip_name} && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" > /tmp/result.log 2>&1 if [ $? != 0 ] then logerror "❌ failed to install connector from zip $connector_zip_name" @@ -521,7 +521,7 @@ else log "🎱 Installing connector $owner/$name:$version_to_get_from_hub" set +e - docker run -u0 -i --rm -v ${DIR_UTILS}/../confluent-hub:/usr/share/confluent-hub-components ${CP_CONNECT_IMAGE}:${CONNECT_TAG} bash -c "confluent-hub install --no-prompt $owner/$name:$version_to_get_from_hub && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" > /tmp/result.log 2>&1 + docker run -u0 -i --rm -v ${DIR_UTILS}/../confluent-hub:/usr/share/confluent-hub-components ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} bash -c "confluent-hub install --no-prompt $owner/$name:$version_to_get_from_hub && chown -R $(id -u $USER):$(id -g $USER) /usr/share/confluent-hub-components" > /tmp/result.log 2>&1 if [ $? != 0 ] then logerror "❌ failed to install connector $owner/$name:$version_to_get_from_hub" @@ -571,9 +571,9 @@ else # Neither CONNECTOR_ZIP or CONNECTOR_JAR are set ### else - if [ -z "$CONNECT_TAG" ] + if [ -z "$CP_CONNECT_TAG" ] then - export CONNECT_TAG="$TAG" + export CP_CONNECT_TAG="$TAG" fi if [ "$first_loop" = true ] then @@ -593,8 +593,8 @@ else fi fi fi - if [ -z "$CONNECT_TAG" ] + if [ -z "$CP_CONNECT_TAG" ] then - export CONNECT_TAG="$TAG" + export CP_CONNECT_TAG="$TAG" fi fi diff --git a/troubleshooting/adding-connect-worker/docker-compose.add-connect-worker.yml b/troubleshooting/adding-connect-worker/docker-compose.add-connect-worker.yml index 829f1748b5..d133d46ac4 100644 --- a/troubleshooting/adding-connect-worker/docker-compose.add-connect-worker.yml +++ b/troubleshooting/adding-connect-worker/docker-compose.add-connect-worker.yml @@ -1,7 +1,7 @@ --- services: connect2: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} hostname: connect2 container_name: connect2 depends_on: diff --git a/troubleshooting/connect-worker-restart-while-broker-down/docker-compose.yml b/troubleshooting/connect-worker-restart-while-broker-down/docker-compose.yml index 7ff496c0a6..30dd926dc0 100644 --- a/troubleshooting/connect-worker-restart-while-broker-down/docker-compose.yml +++ b/troubleshooting/connect-worker-restart-while-broker-down/docker-compose.yml @@ -65,7 +65,7 @@ services: CONFLUENT_METRICS_REPORTER_BOOTSTRAP_SERVERS: broker1:9092,broker2:9092,broker3:9092 connect1: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} hostname: connect1 container_name: connect1 # restart: always @@ -105,7 +105,7 @@ services: # CONNECT_LOG4J_ROOT_LOGLEVEL: DEBUG connect2: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} hostname: connect2 container_name: connect2 restart: always @@ -145,7 +145,7 @@ services: # CONNECT_LOG4J_ROOT_LOGLEVEL: DEBUG connect3: - image: ${CP_CONNECT_IMAGE}:${CONNECT_TAG} + image: ${CP_CONNECT_IMAGE}:${CP_CONNECT_TAG} hostname: connect3 container_name: connect3 # restart: always From b2e34d2caac3713acce3f221cbae37d4f5e5fa5c Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 27 Mar 2025 15:55:37 +0100 Subject: [PATCH 317/659] =?UTF-8?q?=F0=9F=90=B3=20Allow=20to=20override=20?= =?UTF-8?q?all=20CP=20images=20TAG=20#6395?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...docker-compose-connect-onprem-to-cloud.yml | 6 +- ccloud/environment/docker-compose.yml | 4 +- ...ker-compose-executable-onprem-to-cloud.yml | 6 +- .../mirrormaker2/docker-compose.plaintext.yml | 10 +- ...ect-onprem-to-cloud-with-sr-basic-auth.yml | 6 +- ...docker-compose-connect-onprem-to-cloud.yml | 6 +- ...ompose-executable-onprem-to-cloud-avro.yml | 6 +- ...ker-compose-executable-onprem-to-cloud.yml | 6 +- .../docker-compose.yml | 2 +- .../docker-compose.yml | 2 +- environment/kerberos/docker-compose.yml | 4 +- .../docker-compose.yml | 2 +- .../docker-compose.controller.yml | 2 +- environment/mdc-plaintext/docker-compose.yml | 18 ++-- environment/plaintext/docker-compose.yml | 18 ++-- .../docker-compose.mdc-plaintext.yml | 8 +- .../docker-compose.mdc-plaintext.yml | 4 +- .../docker-compose.rbac-sasl-plain.yml | 2 +- other/rebalancer/docker-compose.yml | 16 ++-- .../docker-compose.2way-ssl.yml | 2 +- .../docker-compose.sasl-plain.yml | 2 +- .../docker-compose.sasl-ssl.yml | 2 +- reproduction-models | 2 +- scripts/utils.sh | 91 ++++++++++++++++++- .../docker-compose.yml | 8 +- .../docker-compose.yml | 10 +- .../ksql-avro-ccloud/docker-compose.yml | 4 +- 27 files changed, 166 insertions(+), 83 deletions(-) diff --git a/ccloud/connect-centralized-license/docker-compose-connect-onprem-to-cloud.yml b/ccloud/connect-centralized-license/docker-compose-connect-onprem-to-cloud.yml index ba12969cb9..0592379398 100644 --- a/ccloud/connect-centralized-license/docker-compose-connect-onprem-to-cloud.yml +++ b/ccloud/connect-centralized-license/docker-compose-connect-onprem-to-cloud.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper container_name: zookeeper environment: @@ -12,7 +12,7 @@ services: KAFKA_OPTS: -Dzookeeper.4lw.commands.whitelist=* broker: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker container_name: broker depends_on: @@ -36,7 +36,7 @@ services: KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 schema-registry: - image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${CP_SCHEMA_REGISTRY_TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/ccloud/environment/docker-compose.yml b/ccloud/environment/docker-compose.yml index 296e247657..38042a752b 100644 --- a/ccloud/environment/docker-compose.yml +++ b/ccloud/environment/docker-compose.yml @@ -69,7 +69,7 @@ services: CONNECT_LOG4J_APPENDER_STDOUT_LAYOUT_CONVERSIONPATTERN: "[%d] %p %X{connector.context}%m (%c:%L)%n" control-center: - image: ${CP_CONTROL_CENTER_IMAGE}:${TAG} + image: ${CP_CONTROL_CENTER_IMAGE}:${CP_CONTROL_CENTER_TAG} hostname: control-center container_name: control-center depends_on: @@ -142,7 +142,7 @@ services: # 75147 # schema-registry: - # image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} + # image: ${CP_SCHEMA_REGISTRY_IMAGE}:${CP_SCHEMA_REGISTRY_TAG} # hostname: schema-registry # container_name: schema-registry # ports: diff --git a/ccloud/migrate-schemas-to-confluent-cloud/docker-compose-executable-onprem-to-cloud.yml b/ccloud/migrate-schemas-to-confluent-cloud/docker-compose-executable-onprem-to-cloud.yml index 3282aae25f..ddd53faf22 100644 --- a/ccloud/migrate-schemas-to-confluent-cloud/docker-compose-executable-onprem-to-cloud.yml +++ b/ccloud/migrate-schemas-to-confluent-cloud/docker-compose-executable-onprem-to-cloud.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper container_name: zookeeper environment: @@ -12,7 +12,7 @@ services: KAFKA_OPTS: -Dzookeeper.4lw.commands.whitelist=* broker: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker container_name: broker depends_on: @@ -36,7 +36,7 @@ services: KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 schema-registry: - image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${CP_SCHEMA_REGISTRY_TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/ccloud/mirrormaker2/docker-compose.plaintext.yml b/ccloud/mirrormaker2/docker-compose.plaintext.yml index 2119e1bb14..f8890ed8bc 100644 --- a/ccloud/mirrormaker2/docker-compose.plaintext.yml +++ b/ccloud/mirrormaker2/docker-compose.plaintext.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper container_name: zookeeper environment: @@ -12,7 +12,7 @@ services: KAFKA_OPTS: -Dzookeeper.4lw.commands.whitelist=* broker1: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker1 container_name: broker1 depends_on: @@ -29,7 +29,7 @@ services: broker2: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker2 container_name: broker2 depends_on: @@ -46,7 +46,7 @@ services: broker3: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker3 container_name: broker3 depends_on: @@ -62,7 +62,7 @@ services: KAFKA_MESSAGE_MAX_BYTES: 10048588 schema-registry: - image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${CP_SCHEMA_REGISTRY_TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/ccloud/replicator/docker-compose-connect-onprem-to-cloud-with-sr-basic-auth.yml b/ccloud/replicator/docker-compose-connect-onprem-to-cloud-with-sr-basic-auth.yml index 1a46295237..ed7e1a5176 100644 --- a/ccloud/replicator/docker-compose-connect-onprem-to-cloud-with-sr-basic-auth.yml +++ b/ccloud/replicator/docker-compose-connect-onprem-to-cloud-with-sr-basic-auth.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper container_name: zookeeper environment: @@ -12,7 +12,7 @@ services: KAFKA_OPTS: -Dzookeeper.4lw.commands.whitelist=* broker: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker container_name: broker depends_on: @@ -36,7 +36,7 @@ services: KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 schema-registry: - image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${CP_SCHEMA_REGISTRY_TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/ccloud/replicator/docker-compose-connect-onprem-to-cloud.yml b/ccloud/replicator/docker-compose-connect-onprem-to-cloud.yml index df5300ff83..dff60e5b19 100644 --- a/ccloud/replicator/docker-compose-connect-onprem-to-cloud.yml +++ b/ccloud/replicator/docker-compose-connect-onprem-to-cloud.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper container_name: zookeeper environment: @@ -12,7 +12,7 @@ services: KAFKA_OPTS: -Dzookeeper.4lw.commands.whitelist=* broker: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker container_name: broker depends_on: @@ -36,7 +36,7 @@ services: KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 schema-registry: - image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${CP_SCHEMA_REGISTRY_TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/ccloud/replicator/docker-compose-executable-onprem-to-cloud-avro.yml b/ccloud/replicator/docker-compose-executable-onprem-to-cloud-avro.yml index ac194fd568..2e72265b0d 100644 --- a/ccloud/replicator/docker-compose-executable-onprem-to-cloud-avro.yml +++ b/ccloud/replicator/docker-compose-executable-onprem-to-cloud-avro.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper container_name: zookeeper environment: @@ -12,7 +12,7 @@ services: KAFKA_OPTS: -Dzookeeper.4lw.commands.whitelist=* broker: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker container_name: broker depends_on: @@ -36,7 +36,7 @@ services: KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 schema-registry: - image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${CP_SCHEMA_REGISTRY_TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/ccloud/replicator/docker-compose-executable-onprem-to-cloud.yml b/ccloud/replicator/docker-compose-executable-onprem-to-cloud.yml index ac194fd568..2e72265b0d 100644 --- a/ccloud/replicator/docker-compose-executable-onprem-to-cloud.yml +++ b/ccloud/replicator/docker-compose-executable-onprem-to-cloud.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper container_name: zookeeper environment: @@ -12,7 +12,7 @@ services: KAFKA_OPTS: -Dzookeeper.4lw.commands.whitelist=* broker: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker container_name: broker depends_on: @@ -36,7 +36,7 @@ services: KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 schema-registry: - image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${CP_SCHEMA_REGISTRY_TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/ccloud/rest-proxy-security-plugin/docker-compose.yml b/ccloud/rest-proxy-security-plugin/docker-compose.yml index 7bef9bf755..11170bc768 100644 --- a/ccloud/rest-proxy-security-plugin/docker-compose.yml +++ b/ccloud/rest-proxy-security-plugin/docker-compose.yml @@ -2,7 +2,7 @@ services: restproxy: - image: ${CP_REST_PROXY_IMAGE}:${TAG} + image: ${CP_REST_PROXY_IMAGE}:${CP_REST_PROXY_TAG} restart: always hostname: restproxy container_name: restproxy diff --git a/ccloud/schema-registry-security-plugin/docker-compose.yml b/ccloud/schema-registry-security-plugin/docker-compose.yml index b778782dd6..dce1654ed2 100644 --- a/ccloud/schema-registry-security-plugin/docker-compose.yml +++ b/ccloud/schema-registry-security-plugin/docker-compose.yml @@ -2,7 +2,7 @@ services: schema-registry: - image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${CP_SCHEMA_REGISTRY_TAG} hostname: schema-registry container_name: schema-registry ports: diff --git a/environment/kerberos/docker-compose.yml b/environment/kerberos/docker-compose.yml index b0c61e961f..2d54b0acc3 100644 --- a/environment/kerberos/docker-compose.yml +++ b/environment/kerberos/docker-compose.yml @@ -92,7 +92,7 @@ services: principal=\"admin/for-kafka@TEST.CONFLUENT.IO\";" broker2: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker2.kerberos-demo.local container_name: broker2 depends_on: @@ -151,7 +151,7 @@ services: CONFLUENT_METRICS_ENABLE: 'true' broker3: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker3.kerberos-demo.local container_name: broker3 depends_on: diff --git a/environment/kraft-external-plaintext/docker-compose.yml b/environment/kraft-external-plaintext/docker-compose.yml index 3f06308347..b132588b39 100644 --- a/environment/kraft-external-plaintext/docker-compose.yml +++ b/environment/kraft-external-plaintext/docker-compose.yml @@ -6,7 +6,7 @@ services: - zookeeper controller: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: controller container_name: controller restart: always diff --git a/environment/kraft-plaintext/docker-compose.controller.yml b/environment/kraft-plaintext/docker-compose.controller.yml index f2efcfe3c8..631bff6d78 100644 --- a/environment/kraft-plaintext/docker-compose.controller.yml +++ b/environment/kraft-plaintext/docker-compose.controller.yml @@ -25,7 +25,7 @@ services: controller: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: controller container_name: controller ports: diff --git a/environment/mdc-plaintext/docker-compose.yml b/environment/mdc-plaintext/docker-compose.yml index 5d80a84d38..7edbd843e7 100644 --- a/environment/mdc-plaintext/docker-compose.yml +++ b/environment/mdc-plaintext/docker-compose.yml @@ -8,7 +8,7 @@ services: #### zookeeper-europe: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper-europe container_name: zookeeper-europe environment: @@ -16,7 +16,7 @@ services: ZOOKEEPER_TICK_TIME: 2000 zookeeper-us: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper-us container_name: zookeeper-us environment: @@ -24,7 +24,7 @@ services: ZOOKEEPER_TICK_TIME: 2000 zookeeper-metrics: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper-metrics container_name: zookeeper-metrics environment: @@ -32,7 +32,7 @@ services: ZOOKEEPER_TICK_TIME: 2000 broker-europe: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker-europe container_name: broker-europe depends_on: @@ -60,7 +60,7 @@ services: KAFKA_CONFLUENT_SCHEMA_REGISTRY_URL: http://schema-registry-europe:8081 broker-us: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker-us container_name: broker-us depends_on: @@ -88,7 +88,7 @@ services: KAFKA_CONFLUENT_SCHEMA_REGISTRY_URL: http://schema-registry-us:8081 broker-metrics: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker-metrics container_name: broker-metrics depends_on: @@ -199,7 +199,7 @@ services: - ../../confluent-hub:/usr/share/confluent-hub-components schema-registry-europe: - image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${CP_SCHEMA_REGISTRY_TAG} hostname: schema-registry-europe container_name: schema-registry-europe restart: always @@ -213,7 +213,7 @@ services: SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: broker-europe:9092 schema-registry-us: - image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${CP_SCHEMA_REGISTRY_TAG} hostname: schema-registry-us container_name: schema-registry-us restart: always @@ -227,7 +227,7 @@ services: SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: broker-us:9092 control-center: - image: ${CP_CONTROL_CENTER_IMAGE}:${TAG} + image: ${CP_CONTROL_CENTER_IMAGE}:${CP_CONTROL_CENTER_TAG} hostname: control-center container_name: control-center depends_on: diff --git a/environment/plaintext/docker-compose.yml b/environment/plaintext/docker-compose.yml index 80adabfa6b..416b4cce0e 100644 --- a/environment/plaintext/docker-compose.yml +++ b/environment/plaintext/docker-compose.yml @@ -2,7 +2,7 @@ services: zookeeper: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper container_name: zookeeper restart: always @@ -21,7 +21,7 @@ services: PYROSCOPE_APPLICATION_NAME: "zookeeper" PYROSCOPE_SERVER_ADDRESS: "http://pyroscope:4040" broker: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker container_name: broker restart: always @@ -62,7 +62,7 @@ services: - ../../environment/plaintext/jmx-exporter:/usr/share/jmx_exporter/ broker2: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker2 container_name: broker2 restart: always @@ -104,7 +104,7 @@ services: - ../../environment/plaintext/jmx-exporter:/usr/share/jmx_exporter/ broker3: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker3 container_name: broker3 restart: always @@ -148,7 +148,7 @@ services: schema-registry: - image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${CP_SCHEMA_REGISTRY_TAG} hostname: schema-registry container_name: schema-registry restart: always @@ -389,7 +389,7 @@ services: PYROSCOPE_SERVER_ADDRESS: "http://pyroscope:4040" ksqldb-server: - image: ${CP_KSQL_IMAGE}:${TAG} + image: ${CP_KSQL_IMAGE}:${CP_KSQL_TAG} hostname: ksqldb-server container_name: ksqldb-server depends_on: @@ -432,7 +432,7 @@ services: PYROSCOPE_SERVER_ADDRESS: "http://pyroscope:4040" ksqldb-cli: - image: ${CP_KSQL_CLI_IMAGE} + image: ${CP_KSQL_CLI_IMAGE}:${CP_KSQL_CLI_TAG} container_name: ksqldb-cli depends_on: - broker @@ -444,7 +444,7 @@ services: tty: true control-center: - image: ${CP_CONTROL_CENTER_IMAGE}:${TAG} + image: ${CP_CONTROL_CENTER_IMAGE}:${CP_CONTROL_CENTER_TAG} hostname: control-center container_name: control-center restart: always @@ -483,7 +483,7 @@ services: #CONTROL_CENTER_MODE_ENABLE: management # CONTROL_CENTER_ID: 32 rest-proxy: - image: ${CP_REST_PROXY_IMAGE}:${TAG} + image: ${CP_REST_PROXY_IMAGE}:${CP_REST_PROXY_TAG} hostname: rest-proxy container_name: rest-proxy restart: always diff --git a/other/monitoring-cluster-linking/docker-compose.mdc-plaintext.yml b/other/monitoring-cluster-linking/docker-compose.mdc-plaintext.yml index c77d3d4354..027ee49da4 100644 --- a/other/monitoring-cluster-linking/docker-compose.mdc-plaintext.yml +++ b/other/monitoring-cluster-linking/docker-compose.mdc-plaintext.yml @@ -2,7 +2,7 @@ services: zookeeper-europe: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper-europe container_name: zookeeper-europe restart: always @@ -17,7 +17,7 @@ services: EXTRA_ARGS: "-javaagent:/usr/share/jmx_exporter/jmx_prometheus_javaagent-0.16.1.jar=1234:/usr/share/jmx_exporter/zookeeper.yml" zookeeper-us: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper-us container_name: zookeeper-us restart: always @@ -29,7 +29,7 @@ services: EXTRA_ARGS: "-javaagent:/usr/share/jmx_exporter/jmx_prometheus_javaagent-0.16.1.jar=1234:/usr/share/jmx_exporter/zookeeper.yml" broker-europe: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker-europe container_name: broker-europe cap_add: @@ -54,7 +54,7 @@ services: EXTRA_ARGS: "-javaagent:/usr/share/jmx_exporter/jmx_prometheus_javaagent-0.16.1.jar=1234:/usr/share/jmx_exporter/broker.yml" broker-us: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker-us container_name: broker-us cap_add: diff --git a/other/monitoring-demo/docker-compose.mdc-plaintext.yml b/other/monitoring-demo/docker-compose.mdc-plaintext.yml index 44b33e3910..a4652b2c4d 100644 --- a/other/monitoring-demo/docker-compose.mdc-plaintext.yml +++ b/other/monitoring-demo/docker-compose.mdc-plaintext.yml @@ -10,7 +10,7 @@ services: - ../../other/monitoring-demo/jmx-exporter:/usr/share/jmx_exporter/ zookeeper-europe2: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper-europe2 container_name: zookeeper-europe2 environment: @@ -35,7 +35,7 @@ services: - ../../other/monitoring-demo/jmx-exporter:/usr/share/jmx_exporter/ zookeeper-us2: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper-us2 container_name: zookeeper-us2 environment: diff --git a/other/rbac-with-sr-basic-auth-acl/docker-compose.rbac-sasl-plain.yml b/other/rbac-with-sr-basic-auth-acl/docker-compose.rbac-sasl-plain.yml index dff441f187..bbe9f948d4 100644 --- a/other/rbac-with-sr-basic-auth-acl/docker-compose.rbac-sasl-plain.yml +++ b/other/rbac-with-sr-basic-auth-acl/docker-compose.rbac-sasl-plain.yml @@ -31,7 +31,7 @@ services: - ../../other/rbac-with-sr-basic-auth-acl/scripts/create-acls.sh:/tmp/create-acls.sh schema-registry2: - image: ${CP_SCHEMA_REGISTRY_IMAGE}:${TAG} + image: ${CP_SCHEMA_REGISTRY_IMAGE}:${CP_SCHEMA_REGISTRY_TAG} hostname: schema-registry2 container_name: schema-registry2 restart: always diff --git a/other/rebalancer/docker-compose.yml b/other/rebalancer/docker-compose.yml index 0bf708a2c6..553442c3e3 100644 --- a/other/rebalancer/docker-compose.yml +++ b/other/rebalancer/docker-compose.yml @@ -1,14 +1,14 @@ --- services: zookeeper: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper container_name: zookeeper environment: ZOOKEEPER_CLIENT_PORT: 2181 broker1: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker1 container_name: broker1 depends_on: @@ -23,7 +23,7 @@ services: broker2: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker2 container_name: broker2 depends_on: @@ -38,7 +38,7 @@ services: broker3: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker3 container_name: broker3 depends_on: @@ -53,7 +53,7 @@ services: broker4: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker4 container_name: broker4 depends_on: @@ -68,7 +68,7 @@ services: broker5: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker5 container_name: broker5 depends_on: @@ -83,7 +83,7 @@ services: broker6: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker6 container_name: broker6 depends_on: @@ -98,7 +98,7 @@ services: control-center: - image: ${CP_CONTROL_CENTER_IMAGE}:${TAG} + image: ${CP_CONTROL_CENTER_IMAGE}:${CP_CONTROL_CENTER_TAG} hostname: control-center container_name: control-center depends_on: diff --git a/other/rest-proxy-security-plugin/docker-compose.2way-ssl.yml b/other/rest-proxy-security-plugin/docker-compose.2way-ssl.yml index a4a3380ea9..b66d77c52c 100644 --- a/other/rest-proxy-security-plugin/docker-compose.2way-ssl.yml +++ b/other/rest-proxy-security-plugin/docker-compose.2way-ssl.yml @@ -8,7 +8,7 @@ services: KAFKA_LOG4J_LOGGERS: "kafka.authorizer.logger=INFO" restproxy: - image: ${CP_REST_PROXY_IMAGE}:${TAG} + image: ${CP_REST_PROXY_IMAGE}:${CP_REST_PROXY_TAG} restart: always depends_on: - zookeeper diff --git a/other/rest-proxy-security-plugin/docker-compose.sasl-plain.yml b/other/rest-proxy-security-plugin/docker-compose.sasl-plain.yml index eaf82f3894..fbe1026a13 100644 --- a/other/rest-proxy-security-plugin/docker-compose.sasl-plain.yml +++ b/other/rest-proxy-security-plugin/docker-compose.sasl-plain.yml @@ -20,7 +20,7 @@ services: user_client="client-secret"; restproxy: - image: ${CP_REST_PROXY_IMAGE}:${TAG} + image: ${CP_REST_PROXY_IMAGE}:${CP_REST_PROXY_TAG} restart: always depends_on: - zookeeper diff --git a/other/rest-proxy-security-plugin/docker-compose.sasl-ssl.yml b/other/rest-proxy-security-plugin/docker-compose.sasl-ssl.yml index b57d4ad0a4..791a7053ea 100644 --- a/other/rest-proxy-security-plugin/docker-compose.sasl-ssl.yml +++ b/other/rest-proxy-security-plugin/docker-compose.sasl-ssl.yml @@ -8,7 +8,7 @@ services: KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND: "true" restproxy: - image: ${CP_REST_PROXY_IMAGE}:${TAG} + image: ${CP_REST_PROXY_IMAGE}:${CP_REST_PROXY_TAG} restart: always depends_on: - zookeeper diff --git a/reproduction-models b/reproduction-models index f6b6963431..c5a6b05b9f 160000 --- a/reproduction-models +++ b/reproduction-models @@ -1 +1 @@ -Subproject commit f6b6963431f629a992e58b465068806d23450fb0 +Subproject commit c5a6b05b9f80efedf3b77d862c44b23b784879ee diff --git a/scripts/utils.sh b/scripts/utils.sh index e639d2f6a5..ea7ba1bc99 100755 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -35,7 +35,7 @@ then # TAG is not set, use default: export TAG=7.9.0 # default tag # to handle ubi8 images - export TAG_BASE=$TAG + export TAG_BASE="$TAG" if [ -z "$CP_KAFKA_IMAGE" ] then if [ -z "$IGNORE_CHECK_FOR_DOCKER_COMPOSE" ] && [ -z "$DOCKER_COMPOSE_FILE_UPDATE_VERSION" ] @@ -85,7 +85,47 @@ then if [ -z "$CP_KSQL_CLI_IMAGE" ] then - export CP_KSQL_CLI_IMAGE=confluentinc/cp-ksqldb-cli:latest + export CP_KSQL_CLI_IMAGE=confluentinc/cp-ksqldb-cli + fi + + if [ -z "$CP_ZOOKEEPER_TAG" ] + then + export CP_ZOOKEEPER_TAG="$TAG" + fi + + if [ -z "$CP_KAFKA_TAG" ] + then + export CP_KAFKA_TAG="$TAG" + fi + + if [ -z "$CP_CONNECT_TAG" ] + then + export CP_CONNECT_TAG="$TAG" + fi + + if [ -z "$CP_SCHEMA_REGISTRY_TAG" ] + then + export CP_SCHEMA_REGISTRY_TAG="$TAG" + fi + + if [ -z "$CP_CONTROL_CENTER_TAG" ] + then + export CP_CONTROL_CENTER_TAG="$TAG" + fi + + if [ -z "$CP_REST_PROXY_TAG" ] + then + export CP_REST_PROXY_TAG="$TAG" + fi + + if [ -z "$CP_KSQL_TAG" ] + then + export CP_KSQL_TAG="$TAG" + fi + + if [ -z "$CP_KSQL_CLI_TAG" ] + then + export CP_KSQL_CLI_TAG="latest" fi set_kafka_client_tag else @@ -113,6 +153,41 @@ else then export CP_CONTROL_CENTER_IMAGE=confluentinc/cp-enterprise-control-center fi + + if [ -z "$CP_ZOOKEEPER_TAG" ] + then + export CP_ZOOKEEPER_TAG="$TAG" + fi + + if [ -z "$CP_KAFKA_TAG" ] + then + export CP_KAFKA_TAG="$TAG" + fi + + if [ -z "$CP_CONNECT_TAG" ] + then + export CP_CONNECT_TAG="$TAG" + fi + + if [ -z "$CP_SCHEMA_REGISTRY_TAG" ] + then + export CP_SCHEMA_REGISTRY_TAG="$TAG" + fi + + if [ -z "$CP_CONTROL_CENTER_TAG" ] + then + export CP_CONTROL_CENTER_TAG="$TAG" + fi + + if [ -z "$CP_REST_PROXY_TAG" ] + then + export CP_REST_PROXY_TAG="$TAG" + fi + + if [ -z "$CP_KSQL_TAG" ] + then + export CP_KSQL_TAG="$TAG" + fi # to handle ubi8 images export TAG_BASE=$(echo $TAG | cut -d "-" -f1) first_version=${TAG_BASE} @@ -151,7 +226,11 @@ else fi if [ -z "$CP_KSQL_CLI_IMAGE" ] then - export CP_KSQL_CLI_IMAGE=confluentinc/cp-ksqldb-cli:${TAG_BASE} + export CP_KSQL_CLI_IMAGE=confluentinc/cp-ksqldb-cli + fi + if [ -z "$CP_KSQL_CLI_TAG" ] + then + export CP_KSQL_CLI_TAG=${TAG_BASE} fi else if [ -z "$CP_KSQL_IMAGE" ] @@ -160,7 +239,11 @@ else fi if [ -z "$CP_KSQL_CLI_IMAGE" ] then - export CP_KSQL_CLI_IMAGE=confluentinc/cp-ksql-cli:${TAG_BASE} + export CP_KSQL_CLI_IMAGE=confluentinc/cp-ksql-cli + fi + if [ -z "$CP_KSQL_CLI_TAG" ] + then + export CP_KSQL_CLI_TAG=${TAG_BASE} fi fi second_version=5.2.99 diff --git a/troubleshooting/admin-client-issue-when-broker-down/docker-compose.yml b/troubleshooting/admin-client-issue-when-broker-down/docker-compose.yml index f5b624a326..4ab2187493 100644 --- a/troubleshooting/admin-client-issue-when-broker-down/docker-compose.yml +++ b/troubleshooting/admin-client-issue-when-broker-down/docker-compose.yml @@ -12,14 +12,14 @@ services: container_name: adminclient zookeeper: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper container_name: zookeeper environment: ZOOKEEPER_CLIENT_PORT: 2181 broker1: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker1 container_name: broker1 depends_on: @@ -35,7 +35,7 @@ services: broker2: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker2 container_name: broker2 depends_on: @@ -51,7 +51,7 @@ services: broker3: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker3 container_name: broker3 depends_on: diff --git a/troubleshooting/connect-worker-restart-while-broker-down/docker-compose.yml b/troubleshooting/connect-worker-restart-while-broker-down/docker-compose.yml index 30dd926dc0..e50e147d50 100644 --- a/troubleshooting/connect-worker-restart-while-broker-down/docker-compose.yml +++ b/troubleshooting/connect-worker-restart-while-broker-down/docker-compose.yml @@ -11,14 +11,14 @@ services: zookeeper: - image: ${CP_ZOOKEEPER_IMAGE}:${TAG} + image: ${CP_ZOOKEEPER_IMAGE}:${CP_ZOOKEEPER_TAG} hostname: zookeeper container_name: zookeeper environment: ZOOKEEPER_CLIENT_PORT: 2181 broker1: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker1 container_name: broker1 depends_on: @@ -34,7 +34,7 @@ services: broker2: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker2 container_name: broker2 depends_on: @@ -50,7 +50,7 @@ services: broker3: - image: ${CP_KAFKA_IMAGE}:${TAG} + image: ${CP_KAFKA_IMAGE}:${CP_KAFKA_TAG} hostname: broker3 container_name: broker3 depends_on: @@ -185,7 +185,7 @@ services: # CONNECT_LOG4J_ROOT_LOGLEVEL: DEBUG control-center: - image: ${CP_CONTROL_CENTER_IMAGE}:${TAG} + image: ${CP_CONTROL_CENTER_IMAGE}:${CP_CONTROL_CENTER_TAG} hostname: control-center container_name: control-center depends_on: diff --git a/troubleshooting/ksql-avro-ccloud/docker-compose.yml b/troubleshooting/ksql-avro-ccloud/docker-compose.yml index 0535023b5b..43ae912a3e 100644 --- a/troubleshooting/ksql-avro-ccloud/docker-compose.yml +++ b/troubleshooting/ksql-avro-ccloud/docker-compose.yml @@ -3,7 +3,7 @@ services: ksql-server: - image: ${CP_KSQL_IMAGE}:${TAG} + image: ${CP_KSQL_IMAGE}:${CP_KSQL_TAG} hostname: ksql-server container_name: ksql-server ports: @@ -44,7 +44,7 @@ services: KSQL_CONSUMER_CONFLUENT_MONITORING_INTERCEPTOR_SASL_JAAS_CONFIG: $SASL_JAAS_CONFIG ksql-cli: - image: ${CP_KSQL_CLI_IMAGE} + image: ${CP_KSQL_CLI_IMAGE}:${CP_KSQL_CLI_TAG} container_name: ksql-cli entrypoint: /bin/sh tty: true From 55cde08736ec5813dfcd923b281ef3e9744cc434 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 27 Mar 2025 16:22:24 +0100 Subject: [PATCH 318/659] fix for ngrok --- scripts/cli/src/commands/debug/tcp-dump.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cli/src/commands/debug/tcp-dump.sh b/scripts/cli/src/commands/debug/tcp-dump.sh index 4c09cca956..81aeee06ad 100644 --- a/scripts/cli/src/commands/debug/tcp-dump.sh +++ b/scripts/cli/src/commands/debug/tcp-dump.sh @@ -13,7 +13,7 @@ then if [ "$container" == "ngrok" ] then - playground container exec -c ngrok --command "adduser --force-badname --system --no-create-home _apt" --root > /dev/null 2>&1 + playground container exec -c ngrok --command "adduser --force-badname --system --no-create-home _apt --gid 1000" --root > /dev/null 2>&1 fi docker exec --privileged --user root $container bash -c "apt-get update && echo tcpdump | xargs -n 1 apt-get install --force-yes -y && rm -rf /var/lib/apt/lists/*" > /dev/null 2>&1 fi From 64bfbd011ec077be7e3c8c37baea6ef55f5dcf7b Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Thu, 27 Mar 2025 16:24:36 +0100 Subject: [PATCH 319/659] fix --- scripts/cli/playground | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index e6e6c20bee..3e640d0fc4 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -19621,7 +19621,7 @@ playground_debug_tcp_dump_command() { if [ "$container" == "ngrok" ] then - playground container exec -c ngrok --command "adduser --force-badname --system --no-create-home _apt" --root > /dev/null 2>&1 + playground container exec -c ngrok --command "adduser --force-badname --system --no-create-home _apt --gid 1000" --root > /dev/null 2>&1 fi docker exec --privileged --user root $container bash -c "apt-get update && echo tcpdump | xargs -n 1 apt-get install --force-yes -y && rm -rf /var/lib/apt/lists/*" > /dev/null 2>&1 fi From 5c4a00a7a113b75d7dd86dc08b1ece38e4c4bbf5 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 28 Mar 2025 09:48:49 +0100 Subject: [PATCH 320/659] =?UTF-8?q?=F0=9F=A7=A0=20add=20metadata=20to=20pl?= =?UTF-8?q?ayground=20tools=20read-avro-file=20and=20read-parquet-file=20#?= =?UTF-8?q?6398?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 6 ++++++ scripts/cli/src/commands/tools/read-avro-file.sh | 3 +++ scripts/cli/src/commands/tools/read-parquet-file.sh | 3 +++ 3 files changed, 12 insertions(+) diff --git a/scripts/cli/playground b/scripts/cli/playground index 3e640d0fc4..3c766d86fc 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -19363,6 +19363,9 @@ playground_tools_read_avro_file_command() { filename=$(basename $file) + log "🔖 ${filename}.avro metadata" + docker run --quiet --rm -v ${file}:/tmp/${filename} vdesabou/avro-tools getmeta /tmp/${filename} + log "🔖 ${filename}.avro schema" docker run --quiet --rm -v ${file}:/tmp/${filename} vdesabou/avro-tools getschema /tmp/${filename} @@ -19384,6 +19387,9 @@ playground_tools_read_parquet_file_command() { filename=$(basename $file) + log "🔖 ${filename}.parquet metadata" + docker run --quiet --rm -v ${file}:/tmp/${filename} nathanhowell/parquet-tools meta /tmp/${filename} + log "🔖 ${filename}.parquet schema" docker run --quiet --rm -v ${file}:/tmp/${filename} nathanhowell/parquet-tools schema /tmp/${filename} diff --git a/scripts/cli/src/commands/tools/read-avro-file.sh b/scripts/cli/src/commands/tools/read-avro-file.sh index 44d3da3678..916837341b 100644 --- a/scripts/cli/src/commands/tools/read-avro-file.sh +++ b/scripts/cli/src/commands/tools/read-avro-file.sh @@ -7,6 +7,9 @@ fi filename=$(basename $file) +log "🔖 ${filename}.avro metadata" +docker run --quiet --rm -v ${file}:/tmp/${filename} vdesabou/avro-tools getmeta /tmp/${filename} + log "🔖 ${filename}.avro schema" docker run --quiet --rm -v ${file}:/tmp/${filename} vdesabou/avro-tools getschema /tmp/${filename} diff --git a/scripts/cli/src/commands/tools/read-parquet-file.sh b/scripts/cli/src/commands/tools/read-parquet-file.sh index 3ac22d1918..2ca71d37a8 100644 --- a/scripts/cli/src/commands/tools/read-parquet-file.sh +++ b/scripts/cli/src/commands/tools/read-parquet-file.sh @@ -7,6 +7,9 @@ fi filename=$(basename $file) +log "🔖 ${filename}.parquet metadata" +docker run --quiet --rm -v ${file}:/tmp/${filename} nathanhowell/parquet-tools meta /tmp/${filename} + log "🔖 ${filename}.parquet schema" docker run --quiet --rm -v ${file}:/tmp/${filename} nathanhowell/parquet-tools schema /tmp/${filename} From f5beb7119f445561f22798a402ada3aa8bd13bbd Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 28 Mar 2025 14:33:51 +0100 Subject: [PATCH 321/659] minor --- connect/connect-cdc-oracle11-source/README.md | 2 +- connect/connect-cdc-oracle12-source/README.md | 2 +- connect/connect-cdc-oracle18-source/README.md | 2 +- connect/connect-cdc-oracle19-source/README.md | 9 +-- .../cdc-oracle19-cdb-table-mtls-db-auth.sh | 1 - .../cdc-oracle19-cdb-table-mtls.sh | 1 - .../cdc-oracle19-cdb-table-ssl.sh | 1 - .../cdc-oracle19-cdb-table.sh | 3 +- .../cdc-oracle19-pdb-mview.sh | 1 - .../cdc-oracle19-pdb-table-mtls-db-auth.sh | 1 - .../cdc-oracle19-pdb-table-mtls.sh | 1 - .../cdc-oracle19-pdb-table-ssl.sh | 1 - .../cdc-oracle19-pdb-table.sh | 3 +- connect/connect-cdc-oracle21-source/README.md | 9 +-- .../cdc-oracle21-cdb-table-mtls-db-auth.sh | 80 +++++++++---------- .../cdc-oracle21-cdb-table-mtls.sh | 76 +++++++++--------- .../cdc-oracle21-cdb-table-ssl.sh | 4 +- .../cdc-oracle21-cdb-table.sh | 4 +- .../cdc-oracle21-pdb-mview.sh | 4 +- .../cdc-oracle21-pdb-table-mtls-db-auth.sh | 76 +++++++++--------- .../cdc-oracle21-pdb-table-mtls.sh | 77 +++++++++--------- .../cdc-oracle21-pdb-table-ssl.sh | 1 - .../connect-jdbc-oracle11-source/README.md | 2 +- .../connect-jdbc-oracle12-source/README.md | 2 +- .../connect-jdbc-oracle19-source/README.md | 2 +- .../connect-jdbc-oracle21-source/README.md | 2 +- 26 files changed, 175 insertions(+), 192 deletions(-) diff --git a/connect/connect-cdc-oracle11-source/README.md b/connect/connect-cdc-oracle11-source/README.md index 1df2774134..2d85ec9d1a 100644 --- a/connect/connect-cdc-oracle11-source/README.md +++ b/connect/connect-cdc-oracle11-source/README.md @@ -19,7 +19,7 @@ log "Injecting data for $DURATION minutes" docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --host oracle --username C##MYUSER --password mypassword --sidOrServerName sid --sidOrServerNameVal ORCLCDB --maxPoolSize 10 --durationTimeMin $DURATION" ``` -You can increase thoughtput with `maxPoolSize`. +You can increase throughput with `maxPoolSize`. ## How to run diff --git a/connect/connect-cdc-oracle12-source/README.md b/connect/connect-cdc-oracle12-source/README.md index 2bfffed072..910db3ea21 100644 --- a/connect/connect-cdc-oracle12-source/README.md +++ b/connect/connect-cdc-oracle12-source/README.md @@ -32,7 +32,7 @@ log "Injecting data for $DURATION minutes" docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --host oracle --username C##MYUSER --password mypassword --sidOrServerName sid --sidOrServerNameVal ORCLCDB --maxPoolSize 10 --durationTimeMin $DURATION" ``` -You can increase thoughtput with `maxPoolSize`. +You can increase throughput with `maxPoolSize`. ## How to run diff --git a/connect/connect-cdc-oracle18-source/README.md b/connect/connect-cdc-oracle18-source/README.md index c7b889197c..325cbffd43 100644 --- a/connect/connect-cdc-oracle18-source/README.md +++ b/connect/connect-cdc-oracle18-source/README.md @@ -32,7 +32,7 @@ log "Injecting data for $DURATION minutes" docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --host oracle --username C##MYUSER --password mypassword --sidOrServerName sid --sidOrServerNameVal ORCLCDB --maxPoolSize 10 --durationTimeMin $DURATION" ``` -You can increase thoughtput with `maxPoolSize`. +You can increase throughput with `maxPoolSize`. ## How to run diff --git a/connect/connect-cdc-oracle19-source/README.md b/connect/connect-cdc-oracle19-source/README.md index 9efc3fad14..6ea83f0360 100644 --- a/connect/connect-cdc-oracle19-source/README.md +++ b/connect/connect-cdc-oracle19-source/README.md @@ -15,12 +15,9 @@ Note: The first time you'll run the script, it will build (using this [project]( ![Docker image disk](Screenshot1.png) -## Note on `redo.log.row.fetch.size` +## Note on performance testing -The connector is configured with `"redo.log.row.fetch.size":1` for demo purpose only. -If you're planning to inject more data, it is recommended to increase the value. - -You can set environment variable `SQL_DATAGEN` before running the example and it will use a Java based datagen tool: +You can set environment variable `SQL_DATAGEN` or use `--enable-sql-datagen` with `playground run` before running the example and it will use a Java based datagen tool: Example: @@ -30,7 +27,7 @@ log "Injecting data for $DURATION minutes" docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --host oracle --username C##MYUSER --password mypassword --sidOrServerName sid --sidOrServerNameVal ORCLCDB --maxPoolSize 10 --durationTimeMin $DURATION" ``` -You can increase thoughtput with `maxPoolSize`. +You can increase throughput with `maxPoolSize`. ## How to run diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls-db-auth.sh index 3b3940ecdd..7d92050df8 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls-db-auth.sh @@ -233,7 +233,6 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", "numeric.mapping": "best_fit", "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", "errors.tolerance": "all", "errors.log.enable": "true", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh index c9a60f6828..40155bc6cc 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-mtls.sh @@ -228,7 +228,6 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", "numeric.mapping": "best_fit", "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh index 9ab0a70b6e..8639399252 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table-ssl.sh @@ -199,7 +199,6 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", "numeric.mapping": "best_fit", "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh index b3d9c41893..582121db30 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-cdb-table.sh @@ -9,7 +9,7 @@ create_or_get_oracle_image "LINUX.X64_193000_db_home.zip" "../../connect/connect if [ ! -z "$SQL_DATAGEN" ] then cd ../../connect/connect-cdc-oracle19-source - log "🌪️ SQL_DATAGEN is set, make sure to increase redo.log.row.fetch.size, have a look at https://github.com/vdesabou/kafka-docker-playground/blob/master/connect/connect-cdc-oracle19-source/README.md#note-on-redologrowfetchsize" + log "🌪️ SQL_DATAGEN is set" for component in oracle-datagen do set +e @@ -135,7 +135,6 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", "numeric.mapping": "best_fit", "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-mview.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-mview.sh index f7a9763948..8bfb995e14 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-mview.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-mview.sh @@ -138,7 +138,6 @@ playground connector create-or-update --connector cdc-oracle-source-pdb-mview -- "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", "numeric.mapping": "best_fit", "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh index 7deb2098b2..d860e23586 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls-db-auth.sh @@ -253,7 +253,6 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", "numeric.mapping": "best_fit", "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh index f7fd444f2b..98d00da43d 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-mtls.sh @@ -246,7 +246,6 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", "numeric.mapping": "best_fit", "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh index 7bb1a5dcbf..a68b13a4b2 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table-ssl.sh @@ -216,7 +216,6 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", "numeric.mapping": "best_fit", "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", diff --git a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh index a40952c4fa..3f7517fa3f 100755 --- a/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh +++ b/connect/connect-cdc-oracle19-source/cdc-oracle19-pdb-table.sh @@ -15,7 +15,7 @@ create_or_get_oracle_image "LINUX.X64_193000_db_home.zip" "../../connect/connect if [ ! -z "$SQL_DATAGEN" ] then cd ../../connect/connect-cdc-oracle19-source - log "🌪️ SQL_DATAGEN is set, make sure to increase redo.log.row.fetch.size, have a look at https://github.com/vdesabou/kafka-docker-playground/blob/master/connect/connect-cdc-oracle19-source/README.md#note-on-redologrowfetchsize" + log "🌪️ SQL_DATAGEN is set" for component in oracle-datagen do set +e @@ -152,7 +152,6 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", "numeric.mapping": "best_fit", "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", diff --git a/connect/connect-cdc-oracle21-source/README.md b/connect/connect-cdc-oracle21-source/README.md index a6b82e3d24..45316ba996 100644 --- a/connect/connect-cdc-oracle21-source/README.md +++ b/connect/connect-cdc-oracle21-source/README.md @@ -17,12 +17,9 @@ Note: The first time you'll run the script, it will build (using this [project]( ![Docker image disk](Screenshot1.png) -## Note on `redo.log.row.fetch.size` +## Note on performance testing -The connector is configured with `"redo.log.row.fetch.size":1` for demo purpose only. -If you're planning to inject more data, it is recommended to increase the value. - -You can set environment variable `SQL_DATAGEN` before running the example and it will use a Java based datagen tool: +You can set environment variable `SQL_DATAGEN` or use `--enable-sql-datagen` with `playground run` before running the example and it will use a Java based datagen tool: Example: @@ -32,7 +29,7 @@ log "Injecting data for $DURATION minutes" docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --host oracle --username C##MYUSER --password mypassword --sidOrServerName sid --sidOrServerNameVal ORCLCDB --maxPoolSize 10 --durationTimeMin $DURATION" ``` -You can increase thoughtput with `maxPoolSize`. +You can increase throughput with `maxPoolSize`. ## How to run diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh index 091eb47fdf..123ed1d53b 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls-db-auth.sh @@ -209,46 +209,46 @@ sleep 15 log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { - "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", - "log.sensitive.data": "true", - "tasks.max":1, - "key.converter": "io.confluent.connect.avro.AvroConverter", - "key.converter.schema.registry.url": "http://schema-registry:8081", - "value.converter": "io.confluent.connect.avro.AvroConverter", - "value.converter.schema.registry.url": "http://schema-registry:8081", - "confluent.license": "", - "confluent.topic.bootstrap.servers": "broker:9092", - "confluent.topic.replication.factor": "1", - "oracle.server": "oracle", - "oracle.port": 1532, - "oracle.sid": "ORCLCDB", - "oracle.ssl.truststore.file": "/tmp/truststore.jks", - "oracle.ssl.truststore.password": "welcome123", - "oracle.connection.javax.net.ssl.keyStore": "/tmp/keystore.jks", - "oracle.connection.javax.net.ssl.keyStorePassword": "welcome123", - "oracle.connection.oracle.net.authentication_services": "(TCPS)", - "start.from":"snapshot", - "redo.log.topic.name": "redo-log-topic", - "redo.log.consumer.bootstrap.servers":"broker:9092", - "table.inclusion.regex": ".*CUSTOMERS.*", - "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", - "numeric.mapping": "best_fit", - "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, - "oracle.dictionary.mode": "auto", - "errors.tolerance": "all", - "errors.log.enable": "true", - "errors.log.include.messages": "true", - "topic.creation.groups": "redo", - "topic.creation.redo.include": "redo-log-topic", - "topic.creation.redo.replication.factor": 1, - "topic.creation.redo.partitions": 1, - "topic.creation.redo.cleanup.policy": "delete", - "topic.creation.redo.retention.ms": 1209600000, - "topic.creation.default.replication.factor": 1, - "topic.creation.default.partitions": 1, - "topic.creation.default.cleanup.policy": "delete" - } + "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "log.sensitive.data": "true", + "tasks.max":1, + "key.converter": "io.confluent.connect.avro.AvroConverter", + "key.converter.schema.registry.url": "http://schema-registry:8081", + "value.converter": "io.confluent.connect.avro.AvroConverter", + "value.converter.schema.registry.url": "http://schema-registry:8081", + "confluent.license": "", + "confluent.topic.bootstrap.servers": "broker:9092", + "confluent.topic.replication.factor": "1", + "oracle.server": "oracle", + "oracle.port": 1532, + "oracle.sid": "ORCLCDB", + "oracle.ssl.truststore.file": "/tmp/truststore.jks", + "oracle.ssl.truststore.password": "welcome123", + "oracle.connection.javax.net.ssl.keyStore": "/tmp/keystore.jks", + "oracle.connection.javax.net.ssl.keyStorePassword": "welcome123", + "oracle.connection.oracle.net.authentication_services": "(TCPS)", + "start.from":"snapshot", + "redo.log.topic.name": "redo-log-topic", + "redo.log.consumer.bootstrap.servers":"broker:9092", + "table.inclusion.regex": ".*CUSTOMERS.*", + "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", + "numeric.mapping": "best_fit", + "connection.pool.max.size": 20, + "oracle.dictionary.mode": "auto", + "errors.tolerance": "all", + "errors.log.enable": "true", + "errors.log.include.messages": "true", + "topic.creation.groups": "redo", + "topic.creation.redo.include": "redo-log-topic", + "topic.creation.redo.replication.factor": 1, + "topic.creation.redo.partitions": 1, + "topic.creation.redo.cleanup.policy": "delete", + "topic.creation.redo.retention.ms": 1209600000, + "topic.creation.default.replication.factor": 1, + "topic.creation.default.partitions": 1, + "topic.creation.default.cleanup.policy": "delete", + "use.transaction.begin.for.mining.session": "true" +} EOF log "Waiting 20s for connector to read existing data" diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh index d1172a58a5..cce325729b 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-mtls.sh @@ -201,45 +201,45 @@ wait_container_ready log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-cdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { - "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", "log.sensitive.data": "true", - "tasks.max":1, - "key.converter": "io.confluent.connect.avro.AvroConverter", - "key.converter.schema.registry.url": "http://schema-registry:8081", - "value.converter": "io.confluent.connect.avro.AvroConverter", - "value.converter.schema.registry.url": "http://schema-registry:8081", - "confluent.license": "", - "confluent.topic.bootstrap.servers": "broker:9092", - "confluent.topic.replication.factor": "1", - "oracle.server": "oracle", - "oracle.port": 1532, - "oracle.sid": "ORCLCDB", - "oracle.username": "C##MYUSER", - "oracle.password": "mypassword", - "oracle.ssl.truststore.file": "/tmp/truststore.jks", - "oracle.ssl.truststore.password": "welcome123", - "oracle.connection.javax.net.ssl.keyStore": "/tmp/keystore.jks", - "oracle.connection.javax.net.ssl.keyStorePassword": "welcome123", - "start.from":"snapshot", - "enable.metrics.collection": "true", - "redo.log.topic.name": "redo-log-topic", - "redo.log.consumer.bootstrap.servers":"broker:9092", - "table.inclusion.regex": ".*CUSTOMERS.*", - "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", - "numeric.mapping": "best_fit", - "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, - "oracle.dictionary.mode": "auto", - "topic.creation.groups": "redo", - "topic.creation.redo.include": "redo-log-topic", - "topic.creation.redo.replication.factor": 1, - "topic.creation.redo.partitions": 1, - "topic.creation.redo.cleanup.policy": "delete", - "topic.creation.redo.retention.ms": 1209600000, - "topic.creation.default.replication.factor": 1, - "topic.creation.default.partitions": 1, - "topic.creation.default.cleanup.policy": "delete" - } + "tasks.max":1, + "key.converter": "io.confluent.connect.avro.AvroConverter", + "key.converter.schema.registry.url": "http://schema-registry:8081", + "value.converter": "io.confluent.connect.avro.AvroConverter", + "value.converter.schema.registry.url": "http://schema-registry:8081", + "confluent.license": "", + "confluent.topic.bootstrap.servers": "broker:9092", + "confluent.topic.replication.factor": "1", + "oracle.server": "oracle", + "oracle.port": 1532, + "oracle.sid": "ORCLCDB", + "oracle.username": "C##MYUSER", + "oracle.password": "mypassword", + "oracle.ssl.truststore.file": "/tmp/truststore.jks", + "oracle.ssl.truststore.password": "welcome123", + "oracle.connection.javax.net.ssl.keyStore": "/tmp/keystore.jks", + "oracle.connection.javax.net.ssl.keyStorePassword": "welcome123", + "start.from":"snapshot", + "enable.metrics.collection": "true", + "redo.log.topic.name": "redo-log-topic", + "redo.log.consumer.bootstrap.servers":"broker:9092", + "table.inclusion.regex": ".*CUSTOMERS.*", + "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", + "numeric.mapping": "best_fit", + "connection.pool.max.size": 20, + "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", + "topic.creation.redo.include": "redo-log-topic", + "topic.creation.redo.replication.factor": 1, + "topic.creation.redo.partitions": 1, + "topic.creation.redo.cleanup.policy": "delete", + "topic.creation.redo.retention.ms": 1209600000, + "topic.creation.default.replication.factor": 1, + "topic.creation.default.partitions": 1, + "topic.creation.default.cleanup.policy": "delete", + "use.transaction.begin.for.mining.session": "true" +} EOF log "Waiting 20s for connector to read existing data" diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh index 98ef052330..40f82f7c46 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table-ssl.sh @@ -198,7 +198,6 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", "numeric.mapping": "best_fit", "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", @@ -208,7 +207,8 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "topic.creation.redo.retention.ms": 1209600000, "topic.creation.default.replication.factor": 1, "topic.creation.default.partitions": 1, - "topic.creation.default.cleanup.policy": "delete" + "topic.creation.default.cleanup.policy": "delete", + "use.transaction.begin.for.mining.session": "true" } EOF diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh index 03309ef67f..ed44d5a85e 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-cdb-table.sh @@ -135,7 +135,6 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", "numeric.mapping": "best_fit", "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", @@ -145,7 +144,8 @@ playground connector create-or-update --connector cdc-oracle-source-cdb --packag "topic.creation.redo.retention.ms": 1209600000, "topic.creation.default.replication.factor": 1, "topic.creation.default.partitions": 1, - "topic.creation.default.cleanup.policy": "delete" + "topic.creation.default.cleanup.policy": "delete", + "use.transaction.begin.for.mining.session": "true" } EOF diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-mview.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-mview.sh index 9e80ad78d5..0e33cd5905 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-mview.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-mview.sh @@ -138,7 +138,6 @@ playground connector create-or-update --connector cdc-oracle-source-pdb-mview -- "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", "numeric.mapping": "best_fit", "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", "topic.creation.groups": "redo", "topic.creation.redo.include": "redo-log-topic", @@ -148,7 +147,8 @@ playground connector create-or-update --connector cdc-oracle-source-pdb-mview -- "topic.creation.redo.retention.ms": 1209600000, "topic.creation.default.replication.factor": 1, "topic.creation.default.partitions": 1, - "topic.creation.default.cleanup.policy": "delete" + "topic.creation.default.cleanup.policy": "delete", + "use.transaction.begin.for.mining.session": "true" } EOF diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh index 6072dff6bb..9f0ccb5cfc 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls-db-auth.sh @@ -226,45 +226,45 @@ wait_container_ready log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { - "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", "log.sensitive.data": "true", - "tasks.max":1, - "key.converter": "io.confluent.connect.avro.AvroConverter", - "key.converter.schema.registry.url": "http://schema-registry:8081", - "value.converter": "io.confluent.connect.avro.AvroConverter", - "value.converter.schema.registry.url": "http://schema-registry:8081", - "confluent.license": "", - "confluent.topic.bootstrap.servers": "broker:9092", - "confluent.topic.replication.factor": "1", - "oracle.server": "oracle", - "oracle.port": 1532, - "oracle.sid": "ORCLCDB", - "oracle.pdb.name": "ORCLPDB1", - "oracle.ssl.truststore.file": "/tmp/truststore.jks", - "oracle.ssl.truststore.password": "welcome123", - "oracle.connection.javax.net.ssl.keyStore": "/tmp/keystore.jks", - "oracle.connection.javax.net.ssl.keyStorePassword": "welcome123", - "oracle.connection.oracle.net.authentication_services": "(TCPS)", - "start.from":"snapshot", - "enable.metrics.collection": "true", - "redo.log.topic.name": "redo-log-topic", - "redo.log.consumer.bootstrap.servers":"broker:9092", - "table.inclusion.regex": "ORCLPDB1[.].*[.]CUSTOMERS", - "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", - "numeric.mapping": "best_fit", - "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, - "oracle.dictionary.mode": "auto", - "topic.creation.groups": "redo", - "topic.creation.redo.include": "redo-log-topic", - "topic.creation.redo.replication.factor": 1, - "topic.creation.redo.partitions": 1, - "topic.creation.redo.cleanup.policy": "delete", - "topic.creation.redo.retention.ms": 1209600000, - "topic.creation.default.replication.factor": 1, - "topic.creation.default.partitions": 1, - "topic.creation.default.cleanup.policy": "delete" - } + "tasks.max":1, + "key.converter": "io.confluent.connect.avro.AvroConverter", + "key.converter.schema.registry.url": "http://schema-registry:8081", + "value.converter": "io.confluent.connect.avro.AvroConverter", + "value.converter.schema.registry.url": "http://schema-registry:8081", + "confluent.license": "", + "confluent.topic.bootstrap.servers": "broker:9092", + "confluent.topic.replication.factor": "1", + "oracle.server": "oracle", + "oracle.port": 1532, + "oracle.sid": "ORCLCDB", + "oracle.pdb.name": "ORCLPDB1", + "oracle.ssl.truststore.file": "/tmp/truststore.jks", + "oracle.ssl.truststore.password": "welcome123", + "oracle.connection.javax.net.ssl.keyStore": "/tmp/keystore.jks", + "oracle.connection.javax.net.ssl.keyStorePassword": "welcome123", + "oracle.connection.oracle.net.authentication_services": "(TCPS)", + "start.from":"snapshot", + "enable.metrics.collection": "true", + "redo.log.topic.name": "redo-log-topic", + "redo.log.consumer.bootstrap.servers":"broker:9092", + "table.inclusion.regex": "ORCLPDB1[.].*[.]CUSTOMERS", + "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", + "numeric.mapping": "best_fit", + "connection.pool.max.size": 20, + "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", + "topic.creation.redo.include": "redo-log-topic", + "topic.creation.redo.replication.factor": 1, + "topic.creation.redo.partitions": 1, + "topic.creation.redo.cleanup.policy": "delete", + "topic.creation.redo.retention.ms": 1209600000, + "topic.creation.default.replication.factor": 1, + "topic.creation.default.partitions": 1, + "topic.creation.default.cleanup.policy": "delete", + "use.transaction.begin.for.mining.session": "true" +} EOF log "Waiting 20s for connector to read existing data" diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh index 8595353102..1aa185eb3f 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-mtls.sh @@ -218,46 +218,45 @@ wait_container_ready log "Creating Oracle source connector" playground connector create-or-update --connector cdc-oracle-source-pdb --package "io.confluent.connect.oracle.cdc.util.metrics.MetricsReporter" --level DEBUG << EOF { - "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", + "connector.class": "io.confluent.connect.oracle.cdc.OracleCdcSourceConnector", "log.sensitive.data": "true", - "tasks.max":1, - "key.converter": "io.confluent.connect.avro.AvroConverter", - "key.converter.schema.registry.url": "http://schema-registry:8081", - "value.converter": "io.confluent.connect.avro.AvroConverter", - "value.converter.schema.registry.url": "http://schema-registry:8081", - "confluent.license": "", - "confluent.topic.bootstrap.servers": "broker:9092", - "confluent.topic.replication.factor": "1", - "oracle.server": "oracle", - "oracle.port": 1532, - "oracle.sid": "ORCLCDB", - "oracle.pdb.name": "ORCLPDB1", - "oracle.username": "C##MYUSER", - "oracle.password": "mypassword", - "oracle.ssl.truststore.file": "/tmp/truststore.jks", - "oracle.ssl.truststore.password": "welcome123", - "oracle.connection.javax.net.ssl.keyStore": "/tmp/keystore.jks", - "oracle.connection.javax.net.ssl.keyStorePassword": "welcome123", - "start.from":"snapshot", - "enable.metrics.collection": "true", - "redo.log.topic.name": "redo-log-topic", - "redo.log.consumer.bootstrap.servers":"broker:9092", - "table.inclusion.regex": "ORCLPDB1[.].*[.]CUSTOMERS", - "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", - "numeric.mapping": "best_fit", - "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, - "oracle.dictionary.mode": "auto", - "topic.creation.groups": "redo", - "topic.creation.redo.include": "redo-log-topic", - "topic.creation.redo.replication.factor": 1, - "topic.creation.redo.partitions": 1, - "topic.creation.redo.cleanup.policy": "delete", - "topic.creation.redo.retention.ms": 1209600000, - "topic.creation.default.replication.factor": 1, - "topic.creation.default.partitions": 1, - "topic.creation.default.cleanup.policy": "delete" - } + "tasks.max":1, + "key.converter": "io.confluent.connect.avro.AvroConverter", + "key.converter.schema.registry.url": "http://schema-registry:8081", + "value.converter": "io.confluent.connect.avro.AvroConverter", + "value.converter.schema.registry.url": "http://schema-registry:8081", + "confluent.license": "", + "confluent.topic.bootstrap.servers": "broker:9092", + "confluent.topic.replication.factor": "1", + "oracle.server": "oracle", + "oracle.port": 1532, + "oracle.sid": "ORCLCDB", + "oracle.pdb.name": "ORCLPDB1", + "oracle.username": "C##MYUSER", + "oracle.password": "mypassword", + "oracle.ssl.truststore.file": "/tmp/truststore.jks", + "oracle.ssl.truststore.password": "welcome123", + "oracle.connection.javax.net.ssl.keyStore": "/tmp/keystore.jks", + "oracle.connection.javax.net.ssl.keyStorePassword": "welcome123", + "start.from":"snapshot", + "enable.metrics.collection": "true", + "redo.log.topic.name": "redo-log-topic", + "redo.log.consumer.bootstrap.servers":"broker:9092", + "table.inclusion.regex": "ORCLPDB1[.].*[.]CUSTOMERS", + "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", + "numeric.mapping": "best_fit", + "connection.pool.max.size": 20, + "oracle.dictionary.mode": "auto", + "topic.creation.groups": "redo", + "topic.creation.redo.include": "redo-log-topic", + "topic.creation.redo.replication.factor": 1, + "topic.creation.redo.partitions": 1, + "topic.creation.redo.cleanup.policy": "delete", + "topic.creation.redo.retention.ms": 1209600000, + "topic.creation.default.replication.factor": 1, + "topic.creation.default.partitions": 1, + "topic.creation.default.cleanup.policy": "delete" + } EOF log "Waiting 20s for connector to read existing data" diff --git a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh index bc9d91f78c..973ad6dd1b 100755 --- a/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh +++ b/connect/connect-cdc-oracle21-source/cdc-oracle21-pdb-table-ssl.sh @@ -216,7 +216,6 @@ playground connector create-or-update --connector cdc-oracle-source-pdb --packag "table.topic.name.template": "\${databaseName}.\${schemaName}.\${tableName}", "numeric.mapping": "best_fit", "connection.pool.max.size": 20, - "redo.log.row.fetch.size":1, "oracle.dictionary.mode": "auto", "topic.creation.redo.include": "redo-log-topic", "topic.creation.redo.replication.factor": 1, diff --git a/connect/connect-jdbc-oracle11-source/README.md b/connect/connect-jdbc-oracle11-source/README.md index 323941ff98..d2a7d68cca 100644 --- a/connect/connect-jdbc-oracle11-source/README.md +++ b/connect/connect-jdbc-oracle11-source/README.md @@ -22,7 +22,7 @@ log "Injecting data for $DURATION minutes" docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --host oracle --username C##MYUSER --password mypassword --sidOrServerName sid --sidOrServerNameVal XE --maxPoolSize 10 --durationTimeMin $DURATION" ``` -You can increase thoughtput with `maxPoolSize`. +You can increase throughput with `maxPoolSize`. ## How to run diff --git a/connect/connect-jdbc-oracle12-source/README.md b/connect/connect-jdbc-oracle12-source/README.md index ddadf0f0c1..d987e07b45 100644 --- a/connect/connect-jdbc-oracle12-source/README.md +++ b/connect/connect-jdbc-oracle12-source/README.md @@ -30,7 +30,7 @@ log "Injecting data for $DURATION minutes" docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --host oracle --username C##MYUSER --password mypassword --sidOrServerName sid --sidOrServerNameVal ORCLCDB --maxPoolSize 10 --durationTimeMin $DURATION" ``` -You can increase thoughtput with `maxPoolSize`. +You can increase throughput with `maxPoolSize`. ## How to run diff --git a/connect/connect-jdbc-oracle19-source/README.md b/connect/connect-jdbc-oracle19-source/README.md index 21ff867de9..8db0ba67f1 100644 --- a/connect/connect-jdbc-oracle19-source/README.md +++ b/connect/connect-jdbc-oracle19-source/README.md @@ -28,7 +28,7 @@ log "Injecting data for $DURATION minutes" docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --host oracle --username C##MYUSER --password mypassword --sidOrServerName sid --sidOrServerNameVal ORCLCDB --maxPoolSize 10 --durationTimeMin $DURATION" ``` -You can increase thoughtput with `maxPoolSize`. +You can increase throughput with `maxPoolSize`. ## How to run diff --git a/connect/connect-jdbc-oracle21-source/README.md b/connect/connect-jdbc-oracle21-source/README.md index 6697e50f19..923946c6e5 100644 --- a/connect/connect-jdbc-oracle21-source/README.md +++ b/connect/connect-jdbc-oracle21-source/README.md @@ -28,7 +28,7 @@ log "Injecting data for $DURATION minutes" docker exec -d sql-datagen bash -c "java ${JAVA_OPTS} -jar sql-datagen-1.0-SNAPSHOT-jar-with-dependencies.jar --host oracle --username C##MYUSER --password mypassword --sidOrServerName sid --sidOrServerNameVal ORCLCDB --maxPoolSize 10 --durationTimeMin $DURATION" ``` -You can increase thoughtput with `maxPoolSize`. +You can increase throughput with `maxPoolSize`. ## How to run From 2c3cd3c040211188dea9105554d78ae87aa7f6c6 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 28 Mar 2025 14:41:26 +0100 Subject: [PATCH 322/659] =?UTF-8?q?=F0=9F=A7=A0=20automatically=20set=20EN?= =?UTF-8?q?ABLE=5FJMX=5FGRAFANA=20(--enable-jmx-grafana)=20when=20using=20?= =?UTF-8?q?--enable-sql-datagen=20#6400?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 14 ++++++++++++++ scripts/cli/src/commands/run.sh | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/scripts/cli/playground b/scripts/cli/playground index 3c766d86fc..318ea29f68 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -14253,6 +14253,10 @@ playground_run_command() { then array_flag_list+=("--enable-sql-datagen") export SQL_DATAGEN=true + + log "📊 automatically enabling Grafana as --enable-sql-datagen is set" + array_flag_list+=("--enable-jmx-grafana") + export ENABLE_JMX_GRAFANA=true fi if [[ -n "$cluster_type" ]] || [[ -n "$cluster_cloud" ]] || [[ -n "$cluster_region" ]] || [[ -n "$cluster_environment" ]] || [[ -n "$cluster_name" ]] || [[ -n "$cluster_creds" ]] || [[ -n "$cluster_schema_registry_creds" ]] @@ -15094,12 +15098,20 @@ playground_run_command() { array_flag_list+=("--enable-sql-datagen") export SQL_DATAGEN=true interactive_enable_sql="true" + + array_flag_list+=("--enable-jmx-grafana") + export ENABLE_JMX_GRAFANA=true + interactive_enable_grafana="true" fi if [[ $res == *"$MENU_DISABLE_SQL_DATAGEN"* ]] then array_flag_list=("${array_flag_list[@]/"--enable-sql-datagen"}") unset SQL_DATAGEN interactive_enable_sql="" + + array_flag_list=("${array_flag_list[@]/"--enable-jmx-grafana"}") + unset ENABLE_JMX_GRAFANA + interactive_enable_grafana="" fi if [[ $res == *"$MENU_ENVIRONMENT"* ]] @@ -15341,9 +15353,11 @@ playground_run_command() { if [ "$interactive_enable_sql" == "true" ] then + log "📊 automatically enabling Grafana as --enable-sql-datagen is set" if [[ -n "$force_interactive_repro" ]] then force_enable --enable-sql-datagen SQL_DATAGEN + force_enable --enable-jmx-grafana ENABLE_JMX_GRAFANA fi fi diff --git a/scripts/cli/src/commands/run.sh b/scripts/cli/src/commands/run.sh index a4061cb704..03068aebbd 100644 --- a/scripts/cli/src/commands/run.sh +++ b/scripts/cli/src/commands/run.sh @@ -283,6 +283,10 @@ if [[ -n "$enable_sql_datagen" ]] then array_flag_list+=("--enable-sql-datagen") export SQL_DATAGEN=true + + log "📊 automatically enabling Grafana as --enable-sql-datagen is set" + array_flag_list+=("--enable-jmx-grafana") + export ENABLE_JMX_GRAFANA=true fi if [[ -n "$cluster_type" ]] || [[ -n "$cluster_cloud" ]] || [[ -n "$cluster_region" ]] || [[ -n "$cluster_environment" ]] || [[ -n "$cluster_name" ]] || [[ -n "$cluster_creds" ]] || [[ -n "$cluster_schema_registry_creds" ]] @@ -1114,12 +1118,20 @@ then array_flag_list+=("--enable-sql-datagen") export SQL_DATAGEN=true interactive_enable_sql="true" + + array_flag_list+=("--enable-jmx-grafana") + export ENABLE_JMX_GRAFANA=true + interactive_enable_grafana="true" fi if [[ $res == *"$MENU_DISABLE_SQL_DATAGEN"* ]] then array_flag_list=("${array_flag_list[@]/"--enable-sql-datagen"}") unset SQL_DATAGEN interactive_enable_sql="" + + array_flag_list=("${array_flag_list[@]/"--enable-jmx-grafana"}") + unset ENABLE_JMX_GRAFANA + interactive_enable_grafana="" fi if [[ $res == *"$MENU_ENVIRONMENT"* ]] @@ -1361,9 +1373,11 @@ then if [ "$interactive_enable_sql" == "true" ] then + log "📊 automatically enabling Grafana as --enable-sql-datagen is set" if [[ -n "$force_interactive_repro" ]] then force_enable --enable-sql-datagen SQL_DATAGEN + force_enable --enable-jmx-grafana ENABLE_JMX_GRAFANA fi fi From 0f65a7243da8b39d160bda46a858f642da878bbf Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Fri, 28 Mar 2025 16:26:36 +0100 Subject: [PATCH 323/659] =?UTF-8?q?=F0=9F=A7=A0=20automatically=20automati?= =?UTF-8?q?cally=20enabling=20Grafana=20and=20SQL=20Datagen=20injection=20?= =?UTF-8?q?(when=20applicable)=20when=20repro=20model=20name=20contains=20?= =?UTF-8?q?"perf"=20#6399?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/cli/playground | 36 ++++++++++++++++++++- scripts/cli/src/commands/repro/bootstrap.sh | 15 ++++++++- scripts/cli/src/commands/run.sh | 20 +++++++++++- scripts/cli/src/lib/cli_function.sh | 2 ++ 4 files changed, 70 insertions(+), 3 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 318ea29f68..8af5cbbf71 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -8112,6 +8112,8 @@ function check_for_ec2_instance_running() { # loop through the list for instance in $(echo $current_list | tr "|" "\n") do + echo "" + echo "" log "💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸" log "🤑 you have an ec2 instance $instance running !" log "💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸" @@ -14241,6 +14243,11 @@ playground_run_command() { fi array_flag_list+=("--enable-jmx-grafana") export ENABLE_JMX_GRAFANA=true + + if [[ -n "$force_interactive_repro" ]] + then + force_enable --enable-jmx-grafana ENABLE_JMX_GRAFANA + fi fi if [[ -n "$enable_kcat" ]] @@ -14257,6 +14264,12 @@ playground_run_command() { log "📊 automatically enabling Grafana as --enable-sql-datagen is set" array_flag_list+=("--enable-jmx-grafana") export ENABLE_JMX_GRAFANA=true + + if [[ -n "$force_interactive_repro" ]] + then + force_enable --enable-sql-datagen SQL_DATAGEN + force_enable --enable-jmx-grafana ENABLE_JMX_GRAFANA + fi fi if [[ -n "$cluster_type" ]] || [[ -n "$cluster_cloud" ]] || [[ -n "$cluster_region" ]] || [[ -n "$cluster_environment" ]] || [[ -n "$cluster_name" ]] || [[ -n "$cluster_creds" ]] || [[ -n "$cluster_schema_registry_creds" ]] @@ -15551,6 +15564,13 @@ playground_run_command() { display_docker_container_error_log fi check_for_ec2_instance_running + + if [ ! -z "$ENABLE_JMX_GRAFANA" ] + then + log "🛡️ Prometheus is reachable at http://127.0.0.1:9090" + log "📛 Pyroscope is reachable at http://127.0.0.1:4040" + log "📊 Grafana is reachable at http://127.0.0.1:3000 (login/password is admin/password) or JMX metrics are available locally on those ports:" + fi } # :command.function @@ -18137,7 +18157,21 @@ EOF playground generate-fzf-find-files & playground open-docs --only-show-url - playground run -f $repro_dir/$repro_test_filename --force-interactive-repro $flag_list + + if [[ "$repro_test_filename" == *"perf"* ]] + then + if [[ $test_file == *"connect-debezium-sqlserver"* ]] || [[ $test_file == *"connect-debezium-mysql"* ]] || [[ $test_file == *"connect-debezium-postgresql"* ]] || [[ $test_file == *"connect-debezium-oracle"* ]] || [[ $test_file == *"connect-cdc-oracle"* ]] || [[ $test_file == *"connect-jdbc-sqlserver"* ]] || [[ $test_file == *"connect-jdbc-mysql"* ]] || [[ $test_file == *"connect-jdbc-postgresql"* ]] || [[ $test_file == *"connect-jdbc-oracle"* ]] || [[ $test_file == *"connect-cdc-xstream"* ]] + then + log "🌪️ automatically enabling SQL Datagen injection as repro name contains " + playground run -f $repro_dir/$repro_test_filename --enable-sql-datagen --force-interactive-repro $flag_list + else + log "📊 automatically enabling Grafana as repro name contains " + playground run -f $repro_dir/$repro_test_filename --enable-jmx-grafana --force-interactive-repro $flag_list + fi + else + playground run -f $repro_dir/$repro_test_filename --force-interactive-repro $flag_list + fi + } # :command.function diff --git a/scripts/cli/src/commands/repro/bootstrap.sh b/scripts/cli/src/commands/repro/bootstrap.sh index d5d67c94a3..072e864e87 100644 --- a/scripts/cli/src/commands/repro/bootstrap.sh +++ b/scripts/cli/src/commands/repro/bootstrap.sh @@ -1279,4 +1279,17 @@ log "🛠️ Number of repro models available: $(get_cli_metric nb_existing_repr playground generate-fzf-find-files & playground open-docs --only-show-url -playground run -f $repro_dir/$repro_test_filename --force-interactive-repro $flag_list \ No newline at end of file + +if [[ "$repro_test_filename" == *"perf"* ]] +then + if [[ $test_file == *"connect-debezium-sqlserver"* ]] || [[ $test_file == *"connect-debezium-mysql"* ]] || [[ $test_file == *"connect-debezium-postgresql"* ]] || [[ $test_file == *"connect-debezium-oracle"* ]] || [[ $test_file == *"connect-cdc-oracle"* ]] || [[ $test_file == *"connect-jdbc-sqlserver"* ]] || [[ $test_file == *"connect-jdbc-mysql"* ]] || [[ $test_file == *"connect-jdbc-postgresql"* ]] || [[ $test_file == *"connect-jdbc-oracle"* ]] || [[ $test_file == *"connect-cdc-xstream"* ]] + then + log "🌪️ automatically enabling SQL Datagen injection as repro name contains " + playground run -f $repro_dir/$repro_test_filename --enable-sql-datagen --force-interactive-repro $flag_list + else + log "📊 automatically enabling Grafana as repro name contains " + playground run -f $repro_dir/$repro_test_filename --enable-jmx-grafana --force-interactive-repro $flag_list + fi +else + playground run -f $repro_dir/$repro_test_filename --force-interactive-repro $flag_list +fi diff --git a/scripts/cli/src/commands/run.sh b/scripts/cli/src/commands/run.sh index 03068aebbd..9f1a5b3169 100644 --- a/scripts/cli/src/commands/run.sh +++ b/scripts/cli/src/commands/run.sh @@ -271,6 +271,11 @@ then fi array_flag_list+=("--enable-jmx-grafana") export ENABLE_JMX_GRAFANA=true + + if [[ -n "$force_interactive_repro" ]] + then + force_enable --enable-jmx-grafana ENABLE_JMX_GRAFANA + fi fi if [[ -n "$enable_kcat" ]] @@ -287,6 +292,12 @@ then log "📊 automatically enabling Grafana as --enable-sql-datagen is set" array_flag_list+=("--enable-jmx-grafana") export ENABLE_JMX_GRAFANA=true + + if [[ -n "$force_interactive_repro" ]] + then + force_enable --enable-sql-datagen SQL_DATAGEN + force_enable --enable-jmx-grafana ENABLE_JMX_GRAFANA + fi fi if [[ -n "$cluster_type" ]] || [[ -n "$cluster_cloud" ]] || [[ -n "$cluster_region" ]] || [[ -n "$cluster_environment" ]] || [[ -n "$cluster_name" ]] || [[ -n "$cluster_creds" ]] || [[ -n "$cluster_schema_registry_creds" ]] @@ -1570,4 +1581,11 @@ else display_docker_container_error_log fi -check_for_ec2_instance_running \ No newline at end of file +check_for_ec2_instance_running + +if [ ! -z "$ENABLE_JMX_GRAFANA" ] +then + log "🛡️ Prometheus is reachable at http://127.0.0.1:9090" + log "📛 Pyroscope is reachable at http://127.0.0.1:4040" + log "📊 Grafana is reachable at http://127.0.0.1:3000 (login/password is admin/password) or JMX metrics are available locally on those ports:" +fi \ No newline at end of file diff --git a/scripts/cli/src/lib/cli_function.sh b/scripts/cli/src/lib/cli_function.sh index 2f1b18e651..ae20afe60d 100644 --- a/scripts/cli/src/lib/cli_function.sh +++ b/scripts/cli/src/lib/cli_function.sh @@ -1617,6 +1617,8 @@ function check_for_ec2_instance_running() { # loop through the list for instance in $(echo $current_list | tr "|" "\n") do + echo "" + echo "" log "💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸" log "🤑 you have an ec2 instance $instance running !" log "💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸💸" From fd8117c480cd6e2408619ef416cd588659454421 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 31 Mar 2025 10:56:20 +0200 Subject: [PATCH 324/659] 1.12.744 --- connect/connect-aws-lambda-sink/awscredentialsprovider/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connect/connect-aws-lambda-sink/awscredentialsprovider/pom.xml b/connect/connect-aws-lambda-sink/awscredentialsprovider/pom.xml index ade1a57e5b..758becd7fa 100644 --- a/connect/connect-aws-lambda-sink/awscredentialsprovider/pom.xml +++ b/connect/connect-aws-lambda-sink/awscredentialsprovider/pom.xml @@ -12,7 +12,7 @@ UTF-8 6.2.0 2.8.0 - 1.12.735 + 1.12.744 From 4ff35bb4100af56930d280954eb471070241ff2b Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 31 Mar 2025 11:05:54 +0200 Subject: [PATCH 325/659] minor fix --- scripts/cli/playground | 4 ++-- scripts/cli/src/commands/repro/export.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/cli/playground b/scripts/cli/playground index 8af5cbbf71..aad414de56 100755 --- a/scripts/cli/playground +++ b/scripts/cli/playground @@ -16751,7 +16751,7 @@ playground_repro_export_command() { set +e if [[ -n "$all" ]] then - if [ -d .git ] + if [ -e .git ] then new_files=$(git status --porcelain 2>/dev/null | grep "^?? " | cut -d " " -f2-) if [[ -n "$new_files" ]] @@ -16803,7 +16803,7 @@ playground_repro_export_command() { exit 1 fi - if [ -d .git ] + if [ -e .git ] then cd $test_file_directory diff --git a/scripts/cli/src/commands/repro/export.sh b/scripts/cli/src/commands/repro/export.sh index 8382708910..c16615d230 100644 --- a/scripts/cli/src/commands/repro/export.sh +++ b/scripts/cli/src/commands/repro/export.sh @@ -25,7 +25,7 @@ fi set +e if [[ -n "$all" ]] then - if [ -d .git ] + if [ -e .git ] then new_files=$(git status --porcelain 2>/dev/null | grep "^?? " | cut -d " " -f2-) if [[ -n "$new_files" ]] @@ -76,7 +76,7 @@ else exit 1 fi - if [ -d .git ] + if [ -e .git ] then cd $test_file_directory From b22261e333000310896348d1f191e4fa13c2e472 Mon Sep 17 00:00:00 2001 From: Vincent de Saboulin Date: Mon, 31 Mar 2025 14:57:26 +0200 Subject: [PATCH 326/659] =?UTF-8?q?=F0=9F=93=8A=20Add=20Prometheus=20Grafa?= =?UTF-8?q?na=20Integration=20with=20Confluent=20CCloud=20metrics=20endpoi?= =?UTF-8?q?nt=20#6223?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ccloud/environment/docker-compose.yml | 44 + ccloud/environment/grafana/config/grafana.ini | 894 +++++++ .../grafana/confluent/icon-confluent.svg | 4 + .../grafana/confluent/icon-connector.svg | 11 + .../grafana/confluent/icon-flink.svg | 16 + .../grafana/confluent/icon-kafka.svg | 10 + .../grafana/confluent/icon-ksqldb_rocket.svg | 11 + .../confluent/icon-schema_registry.svg | 9 + .../provisioning/dashboards/ccloud-ksql.json | 672 +++++ .../provisioning/dashboards/ccloud.json | 2382 +++++++++++++++++ .../dashboards/ccloud_billing.json | 2329 ++++++++++++++++ .../provisioning/dashboards/dashboard.yml | 12 + .../provisioning/datasources/datasource.yml | 51 + ccloud/environment/prometheus/prometheus.yml | 25 + ccloud/environment/start.sh | 4 +- scripts/cli/playground | 5 - scripts/cli/src/commands/run.sh | 5 - 17 files changed, 6472 insertions(+), 12 deletions(-) create mode 100644 ccloud/environment/grafana/config/grafana.ini create mode 100644 ccloud/environment/grafana/confluent/icon-confluent.svg create mode 100644 ccloud/environment/grafana/confluent/icon-connector.svg create mode 100644 ccloud/environment/grafana/confluent/icon-flink.svg create mode 100644 ccloud/environment/grafana/confluent/icon-kafka.svg create mode 100644 ccloud/environment/grafana/confluent/icon-ksqldb_rocket.svg create mode 100644 ccloud/environment/grafana/confluent/icon-schema_registry.svg create mode 100644 ccloud/environment/grafana/provisioning/dashboards/ccloud-ksql.json create mode 100644 ccloud/environment/grafana/provisioning/dashboards/ccloud.json create mode 100644 ccloud/environment/grafana/provisioning/dashboards/ccloud_billing.json create mode 100644 ccloud/environment/grafana/provisioning/dashboards/dashboard.yml create mode 100644 ccloud/environment/grafana/provisioning/datasources/datasource.yml create mode 100644 ccloud/environment/prometheus/prometheus.yml diff --git a/ccloud/environment/docker-compose.yml b/ccloud/environment/docker-compose.yml index 38042a752b..eb959bc1da 100644 --- a/ccloud/environment/docker-compose.yml +++ b/ccloud/environment/docker-compose.yml @@ -140,6 +140,50 @@ services: profiles: - "conduktor" + prometheus: + image: prom/prometheus:v2.29.2 + hostname: prometheus + container_name: prometheus + profiles: + - "grafana" + ports: + - 9090:9090 + volumes: + - ./prometheus/:/etc/prometheus/ + + grafana: + image: grafana/grafana:11.1.0 + hostname: grafana + container_name: grafana + profiles: + - "grafana" + environment: + - "GF_SECURITY_ADMIN_USER=admin" + - "GF_SECURITY_ADMIN_PASSWORD=password" + - "GF_USERS_ALLOW_SIGN_UP=false" + ports: + - 3000:3000 + volumes: + - ./grafana/provisioning/:/etc/grafana/provisioning/ + - ./grafana/config/grafana.ini:/etc/grafana/grafana.ini + - ./grafana/confluent:/usr/share/grafana/public/img/icons/confluent + depends_on: + - prometheus + + confluent_cost_exporter: + profiles: + - "grafana" + image: docker.io/mcolomerc/confluent-costs-exporter:latest + #platform: linux/amd64 + container_name: confluent_cost_exporter + environment: + - CONFLUENT_CLOUD_API_KEY=$CLOUD_API_KEY + - CONFLUENT_CLOUD_API_SECRET=$CLOUD_API_SECRET + - CACHE_EXPIRATION=240m + - PORT=7979 + ports: + - 7979:7979 + # 75147 # schema-registry: # image: ${CP_SCHEMA_REGISTRY_IMAGE}:${CP_SCHEMA_REGISTRY_TAG} diff --git a/ccloud/environment/grafana/config/grafana.ini b/ccloud/environment/grafana/config/grafana.ini new file mode 100644 index 0000000000..9fe327159a --- /dev/null +++ b/ccloud/environment/grafana/config/grafana.ini @@ -0,0 +1,894 @@ +##################### Grafana Configuration Example ##################### +# +# Everything has defaults so you only need to uncomment things you want to +# change + +# possible values : production, development +;app_mode = production + +# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty +;instance_name = ${HOSTNAME} + +#################################### Paths #################################### +[paths] +# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used) +;data = /var/lib/grafana + +# Temporary files in `data` directory older than given duration will be removed +;temp_data_lifetime = 24h + +# Directory where grafana can store logs +;logs = /var/log/grafana + +# Directory where grafana will automatically scan and look for plugins +;plugins = /var/lib/grafana/plugins + +# folder that contains provisioning config files that grafana will apply on startup and while running. +;provisioning = conf/provisioning + +#################################### Server #################################### +[server] +# Protocol (http, https, h2, socket) +;protocol = http + +# The ip address to bind to, empty will bind to all interfaces +;http_addr = + +# The http port to use +;http_port = 3000 + +# The public facing domain name used to access grafana from a browser +;domain = localhost + +# Redirect to correct domain if host header does not match domain +# Prevents DNS rebinding attacks +;enforce_domain = false + +# The full public facing url you use in browser, used for redirects and emails +# If you use reverse proxy and sub path specify full url (with sub path) +;root_url = %(protocol)s://%(domain)s:%(http_port)s/ + +# Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons. +;serve_from_sub_path = false + +# Log web requests +;router_logging = false + +# the path relative working path +;static_root_path = public + +# enable gzip +;enable_gzip = false + +# https certs & key file +;cert_file = +;cert_key = + +# Unix socket path +;socket = + +# CDN Url +;cdn_url = + +#################################### Database #################################### +[database] +# You can configure the database connection by specifying type, host, name, user and password +# as separate properties or as on string using the url properties. + +# Either "mysql", "postgres" or "sqlite3", it's your choice +;type = sqlite3 +;host = 127.0.0.1:3306 +;name = grafana +;user = root +# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;""" +;password = + +# Use either URL or the previous fields to configure the database +# Example: mysql://user:secret@host:port/database +;url = + +# For "postgres" only, either "disable", "require" or "verify-full" +;ssl_mode = disable + +;ca_cert_path = +;client_key_path = +;client_cert_path = +;server_cert_name = + +# For "sqlite3" only, path relative to data_path setting +;path = grafana.db + +# Max idle conn setting default is 2 +;max_idle_conn = 2 + +# Max conn setting default is 0 (mean not set) +;max_open_conn = + +# Connection Max Lifetime default is 14400 (means 14400 seconds or 4 hours) +;conn_max_lifetime = 14400 + +# Set to true to log the sql calls and execution times. +;log_queries = + +# For "sqlite3" only. cache mode setting used for connecting to the database. (private, shared) +;cache_mode = private + +################################### Data sources ######################### +[datasources] +# Upper limit of data sources that Grafana will return. This limit is a temporary configuration and it will be deprecated when pagination will be introduced on the list data sources API. +;datasource_limit = 5000 + +#################################### Cache server ############################# +[remote_cache] +# Either "redis", "memcached" or "database" default is "database" +;type = database + +# cache connectionstring options +# database: will use Grafana primary database. +# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0,ssl=false`. Only addr is required. ssl may be 'true', 'false', or 'insecure'. +# memcache: 127.0.0.1:11211 +;connstr = + +#################################### Data proxy ########################### +[dataproxy] + +# This enables data proxy logging, default is false +;logging = false + +# How long the data proxy waits before timing out, default is 30 seconds. +# This setting also applies to core backend HTTP data sources where query requests use an HTTP client with timeout set. +;timeout = 30 + +# How many seconds the data proxy waits before sending a keepalive probe request. +;keep_alive_seconds = 30 + +# How many seconds the data proxy waits for a successful TLS Handshake before timing out. +;tls_handshake_timeout_seconds = 10 + +# How many seconds the data proxy will wait for a server's first response headers after +# fully writing the request headers if the request has an "Expect: 100-continue" +# header. A value of 0 will result in the body being sent immediately, without +# waiting for the server to approve. +;expect_continue_timeout_seconds = 1 + +# The maximum number of idle connections that Grafana will keep alive. +;max_idle_connections = 100 + +# How many seconds the data proxy keeps an idle connection open before timing out. +;idle_conn_timeout_seconds = 90 + +# If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request, default is false. +;send_user_header = false + +#################################### Analytics #################################### +[analytics] +# Server reporting, sends usage counters to stats.grafana.org every 24 hours. +# No ip addresses are being tracked, only simple counters to track +# running instances, dashboard and error counts. It is very helpful to us. +# Change this option to false to disable reporting. +;reporting_enabled = true + +# The name of the distributor of the Grafana instance. Ex hosted-grafana, grafana-labs +;reporting_distributor = grafana-labs + +# Set to false to disable all checks to https://grafana.net +# for new versions (grafana itself and plugins), check is used +# in some UI views to notify that grafana or plugin update exists +# This option does not cause any auto updates, nor send any information +# only a GET request to http://grafana.com to get latest versions +;check_for_updates = true + +# Google Analytics universal tracking code, only enabled if you specify an id here +;google_analytics_ua_id = + +# Google Tag Manager ID, only enabled if you specify an id here +;google_tag_manager_id = + +#################################### Security #################################### +[security] +# disable creation of admin user on first start of grafana +;disable_initial_admin_creation = false + +# default admin user, created on startup +;admin_user = admin + +# default admin password, can be changed before first start of grafana, or in profile settings +;admin_password = admin + +# used for signing +;secret_key = SW2YcwTIb9zpOOhoPsMm + +# disable gravatar profile images +;disable_gravatar = false + +# data source proxy whitelist (ip_or_domain:port separated by spaces) +;data_source_proxy_whitelist = + +# disable protection against brute force login attempts +;disable_brute_force_login_protection = false + +# set to true if you host Grafana behind HTTPS. default is false. +;cookie_secure = false + +# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled" +;cookie_samesite = lax + +# set to true if you want to allow browsers to render Grafana in a ,

*)VN+>?fH|?P&}|KH4(%tP0@zN1w6Bmny;Vn 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