From 8bb7929e999dfc2ae4355a86aec90f969f9edd21 Mon Sep 17 00:00:00 2001 From: Sahil Kang Date: Fri, 12 Feb 2021 16:03:11 -0800 Subject: [PATCH] [#53] Update replication.factor inplace (#148) * [#53] Update replication.factor inplace * Update docker, ssl, and tests Since we'll be updating a topic's replication.factor in-place, we need a multi-broker cluster to test against. This is a pretty big diff, but the changes are essentially: * create new secrets to support multiple brokers * update the docker/docker-compose files to support a multi-broker cluster. This cluster can still be run locally with docker-compose up, and CI systems can use the docker-compose.test.yaml to execute a well-defined environment * update the tests to play nicely with the new secrets and docker setup (brokers aren't hard-coded to localhost anymore) * when a topic creation is applied, the resource will be considered 'Pending' until its existence is confirmed via client.ReadTopic. This was less of an issue with one broker, but once we introduced others, the acc tests would sometimes fail because a topic would get created but subsequent steps that ran immediately afterwards wouldn't see it * Update RF before adding partitions If a plan both: * increases the partitions * changes the replication.factor Then there's no point in creating new partitions with the old replication.factor, just to go through and change it immediately afterwards. * Add IsReplicationFactorUpdating method to Client Before we introduced the in-place replication.factor changes, the replication.factor of a topic was updated atomically across all of its partitions: * when the topic was first created, all of its initial partitions had the same rf * when partitions were added to a topic, they would be replicated according to the topic's rf * when a topic's rf was changed, it would be deleted and created again (bullet point 1) Now that a topic's rf may be updated in-place, the rf is not updated atomically; it's instead updated in a rolling/eventually-consistent manner. For sometime after the apply, some partitions will have the new rf, and some will still have the old rf. Eventually, however, they'll all have the new rf. This commit introduces a new method to determine whether or not an rf update has finished propagating through all of a topic's partitions, and changes the kafka_topic resource to be aware of this propagating/updating state. * Add acc tests for in-place rf update Overall flow: * produce a well-known set of messages to a new topic * change that topic's rf and partition count * verify the changes went through and that no messages were lost * Wait for rf update before adding partitions We can't add partitions while a replication.factor update is ongoing, so this commit waits for an rf update to finish before adding any new partitions. Because we're now waiting for the rf to update separately, the IsReplicationFactorUpdating logic has been removed from topicRefreshFunc (which only waits for partition and config updates to finish). * Add CanAlterReplicationFactor method This new method determines if the cluster supports altering a topic's replication.factor in-place. If so, then the provider will go ahead and make alterations in-place; otherwise, it will replace the topic like it did before. populateAPIVersions was changed to ensure that the max api versions are supported by every broker in the cluster. * Send apiVersions request asynchronously to brokers --- .circleci/config.yml | 14 +- Dockerfile | 21 +- Dockerfile.kafka | 32 +++ GNUmakefile | 7 +- docker-compose.testacc.yaml | 15 ++ docker-compose.yaml | 63 +++--- kafka/client.go | 256 ++++++++++++++++++++++-- kafka/config.go | 2 +- kafka/config_test.go | 34 ++-- kafka/lazy_client.go | 24 +++ kafka/provider_test.go | 44 ++++- kafka/resource_kafka_acl_test.go | 19 +- kafka/resource_kafka_topic.go | 130 +++++++++++-- kafka/resource_kafka_topic_test.go | 264 ++++++++++++++++++++++++- secrets/broker1.csr | 18 -- secrets/broker1_keystore_creds | 1 - secrets/broker1_sslkey_creds | 1 - secrets/broker1_truststore_creds | 1 - secrets/ca.crt | 50 +++-- secrets/ca.key | 80 +++++--- secrets/client-no-password.key | 51 +++++ secrets/client.key | 54 ++++++ secrets/client.pem | 32 +++ secrets/create-certs.sh | 278 ++++++++++++++------------- secrets/host.consumer.ssl.config | 9 - secrets/host.producer.ssl.config | 8 - secrets/kafka.broker1.keystore.jks | Bin 4497 -> 0 bytes secrets/kafka.broker1.truststore.jks | Bin 1130 -> 0 bytes secrets/kafka.kafka1.keystore.jks | Bin 0 -> 7591 bytes secrets/kafka.kafka2.keystore.jks | Bin 0 -> 7591 bytes secrets/kafka.kafka3.keystore.jks | Bin 0 -> 7591 bytes secrets/kafka.truststore.jks | Bin 0 -> 1786 bytes secrets/password | 1 + tls-debug/main.go | 2 +- 34 files changed, 1168 insertions(+), 343 deletions(-) create mode 100644 Dockerfile.kafka create mode 100644 docker-compose.testacc.yaml delete mode 100644 secrets/broker1.csr delete mode 100644 secrets/broker1_keystore_creds delete mode 100644 secrets/broker1_sslkey_creds delete mode 100644 secrets/broker1_truststore_creds create mode 100644 secrets/client-no-password.key create mode 100644 secrets/client.key create mode 100644 secrets/client.pem delete mode 100644 secrets/host.consumer.ssl.config delete mode 100644 secrets/host.producer.ssl.config delete mode 100644 secrets/kafka.broker1.keystore.jks delete mode 100644 secrets/kafka.broker1.truststore.jks create mode 100644 secrets/kafka.kafka1.keystore.jks create mode 100644 secrets/kafka.kafka2.keystore.jks create mode 100644 secrets/kafka.kafka3.keystore.jks create mode 100644 secrets/kafka.truststore.jks create mode 100644 secrets/password diff --git a/.circleci/config.yml b/.circleci/config.yml index 33074e26..44dd411a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,18 +19,9 @@ jobs: - image: circleci/golang:1.13 environment: TEST_RESULTS: /tmp/test-results - - image: confluentinc/cp-zookeeper:latest - environment: - ZOOKEEPER_CLIENT_PORT: 2181 - ZOOKEEPER_TICK_TIME: 2000 - - image: mongey/kafka:5.3.3-new-certs - environment: - KAFKA_BROKER_ID: 1 - KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 - KAFKA_ZOOKEEPER_CONNECT: localhost:2181 - KAFKA_LOG_SEGMENT_BYTES: 1234 steps: - checkout + - setup_remote_docker - run: make test - run: go get github.com/jstemmer/go-junit-report - run: mkdir -p $TEST_RESULTS @@ -38,7 +29,8 @@ jobs: name: Run Tests command: | trap "go-junit-report <${TEST_RESULTS}/go-test.out > ${TEST_RESULTS}/go-test-report.xml" EXIT - make testacc| tee ${TEST_RESULTS}/go-test.out + docker-compose -f docker-compose.yaml -f docker-compose.testacc.yaml up \ + --abort-on-container-exit testacc | tee ${TEST_RESULTS}/go-test.out - store_test_results: path: /tmp/test-results diff --git a/Dockerfile b/Dockerfile index 3301048b..3ccc5b7e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,7 @@ -FROM confluentinc/cp-kafka:5.3.3 -COPY secrets/ /etc/kafka/secrets +FROM golang:1.13 -ENV KAFKA_ADVERTISED_LISTENERS=SSL://localhost:9092 -ENV KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 -ENV KAFKA_SSL_KEYSTORE_FILENAME=kafka.broker1.keystore.jks -ENV KAFKA_SSL_KEYSTORE_CREDENTIALS=broker1_keystore_creds -ENV KAFKA_SSL_KEY_CREDENTIALS=broker1_sslkey_creds -ENV KAFKA_SSL_TRUSTSTORE_FILENAME=kafka.broker1.truststore.jks -ENV KAFKA_SSL_TRUSTSTORE_CREDENTIALS=broker1_truststore_creds -ENV KAFKA_SECURITY_INTER_BROKER_PROTOCOL=SSL -ENV KAFKA_SSL_CLIENT_AUTH=required -ENV KAFKA_SSL_ENDPOINT_IDENTIFICATION_ALGORITHM= -ENV KAFKA_LISTENER_NAME_INTERNAL_SSL_ENDPOINT_IDENTIFICATION_ALGORITHM= -ENV KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND="true" -ENV KAFKA_AUTHORIZER_CLASS_NAME=kafka.security.auth.SimpleAclAuthorizer +WORKDIR /go/src/github.com/Mongey/terraform-provider-kafka/ + +COPY go.mod go.sum main.go GNUmakefile ./ +COPY kafka kafka +COPY secrets secrets diff --git a/Dockerfile.kafka b/Dockerfile.kafka new file mode 100644 index 00000000..9fc41af7 --- /dev/null +++ b/Dockerfile.kafka @@ -0,0 +1,32 @@ +FROM confluentinc/cp-kafka:5.4.1 + +ARG broker_id +ARG zookeeper_connect +ARG listener_host +ARG listener_port + +COPY secrets/ /etc/kafka/secrets + +ENV KAFKA_BROKER_ID=$broker_id +ENV KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 +ENV KAFKA_ZOOKEEPER_CONNECT=$zookeeper_connect + +# confluent's bash script looks for an 'SSL' suffix in listener names: +# https://github.com/confluentinc/cp-docker-images/blob/76d786d0243ea16626b8b46dba34ec0b1066de84/debian/kafka/include/etc/confluent/docker/configure#L65 +ENV KAFKA_LISTENERS=INTERNAL_SSL://$listener_host:9090,EXTERNAL_SSL://$listener_host:9092 +ENV KAFKA_ADVERTISED_LISTENERS=INTERNAL_SSL://$listener_host:9090,EXTERNAL_SSL://localhost:$listener_port +ENV KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=INTERNAL_SSL:SSL,EXTERNAL_SSL:SSL +ENV KAFKA_INTER_BROKER_LISTENER_NAME=INTERNAL_SSL + +ENV KAFKA_SSL_KEYSTORE_FILENAME=kafka.$listener_host.keystore.jks +ENV KAFKA_SSL_KEYSTORE_CREDENTIALS=password + +ENV KAFKA_SSL_TRUSTSTORE_FILENAME=kafka.truststore.jks +ENV KAFKA_SSL_TRUSTSTORE_CREDENTIALS=password + +ENV KAFKA_SSL_KEY_CREDENTIALS=password +ENV KAFKA_SSL_CLIENT_AUTH=required +ENV KAFKA_SSL_ENDPOINT_IDENTIFICATION_ALGORITHM= +ENV KAFKA_LISTENER_NAME_INTERNAL_SSL_ENDPOINT_IDENTIFICATION_ALGORITHM= +ENV KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND=true +ENV KAFKA_AUTHORIZER_CLASS_NAME=kafka.security.auth.SimpleAclAuthorizer diff --git a/GNUmakefile b/GNUmakefile index 582b9a8e..ae455f2c 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -9,11 +9,10 @@ test: go test ./... testacc: - KAFKA_BOOTSTRAP_SERVER=localhost:9092 \ KAFKA_CA_CERT=../secrets/ca.crt \ - KAFKA_CLIENT_CERT=../secrets/terraform-cert.pem \ - KAFKA_CLIENT_KEY=../secrets/terraform-with-passphrase.pem \ - KAFKA_CLIENT_KEY_PASSPHRASE=confluent \ + KAFKA_CLIENT_CERT=../secrets/client.pem \ + KAFKA_CLIENT_KEY=../secrets/client.key \ + KAFKA_CLIENT_KEY_PASSPHRASE=test-pass \ KAFKA_SKIP_VERIFY=false \ KAFKA_ENABLE_TLS=true \ TF_LOG=DEBUG \ diff --git a/docker-compose.testacc.yaml b/docker-compose.testacc.yaml new file mode 100644 index 00000000..a30d5975 --- /dev/null +++ b/docker-compose.testacc.yaml @@ -0,0 +1,15 @@ +--- +version: '3.2' +services: + testacc: + build: . + environment: + KAFKA_BOOTSTRAP_SERVER: kafka1:9090,kafka2:9090,kafka3:9090 + entrypoint: + - make + - testacc + depends_on: + - zookeeper + - kafka1 + - kafka2 + - kafka3 diff --git a/docker-compose.yaml b/docker-compose.yaml index 3d007973..ad9543a6 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -11,31 +11,50 @@ services: extra_hosts: - "moby:127.0.0.1" - kafka: - image: confluentinc/cp-kafka:5.4.1 + kafka1: + build: + context: . + dockerfile: Dockerfile.kafka + args: + broker_id: 1 + zookeeper_connect: zookeeper:2181 + listener_host: kafka1 + listener_port: 9092 ports: - "9092:9092" depends_on: - zookeeper - volumes: - - type: bind - source: ./secrets - target: /etc/kafka/secrets - environment: - KAFKA_BROKER_ID: 1 - KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 - KAFKA_ADVERTISED_LISTENERS: SSL://localhost:9092 - KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 - KAFKA_SSL_KEYSTORE_FILENAME: kafka.broker1.keystore.jks - KAFKA_SSL_KEYSTORE_CREDENTIALS: broker1_keystore_creds - KAFKA_SSL_KEY_CREDENTIALS: broker1_sslkey_creds - KAFKA_SSL_TRUSTSTORE_FILENAME: kafka.broker1.truststore.jks - KAFKA_SSL_TRUSTSTORE_CREDENTIALS: broker1_truststore_creds - KAFKA_SECURITY_INTER_BROKER_PROTOCOL: SSL - KAFKA_SSL_CLIENT_AUTH: required - KAFKA_SSL_ENDPOINT_IDENTIFICATION_ALGORITHM: "" - KAFKA_LISTENER_NAME_INTERNAL_SSL_ENDPOINT_IDENTIFICATION_ALGORITHM: "" - KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND: "true" - KAFKA_AUTHORIZER_CLASS_NAME: kafka.security.auth.SimpleAclAuthorizer + extra_hosts: + - "moby:127.0.0.1" + + kafka2: + build: + context: . + dockerfile: Dockerfile.kafka + args: + broker_id: 2 + zookeeper_connect: zookeeper:2181 + listener_host: kafka2 + listener_port: 9093 + ports: + - "9093:9092" + depends_on: + - zookeeper + extra_hosts: + - "moby:127.0.0.1" + + kafka3: + build: + context: . + dockerfile: Dockerfile.kafka + args: + broker_id: 3 + zookeeper_connect: zookeeper:2181 + listener_host: kafka3 + listener_port: 9094 + ports: + - "9094:9092" + depends_on: + - zookeeper extra_hosts: - "moby:127.0.0.1" diff --git a/kafka/client.go b/kafka/client.go index 8bdb75ca..b11463c2 100644 --- a/kafka/client.go +++ b/kafka/client.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "time" + "math/rand" "github.com/Shopify/sarama" ) @@ -65,29 +66,105 @@ func (c *Client) SaramaClient() sarama.Client { } func (c *Client) populateAPIVersions() error { - log.Printf("[DEBUG] retrieving supported APIs from broker: %s", c.config.BootstrapServers) - broker, err := c.client.Controller() - if err != nil { - log.Printf("[ERROR] Unable to populate supported API versions. Error retrieving controller: %s", err) - return err + ch := make(chan []*sarama.ApiVersionsResponseBlock) + errCh := make(chan error) + + brokers := c.client.Brokers() + kafkaConfig := c.kafkaConfig + for _, broker := range brokers { + go apiVersionsFromBroker(broker, kafkaConfig, ch, errCh) + } + + clusterApiVersions := make(map[int][2]int) // valid api version intervals across all brokers + errs := make([]error, 0) + for i := 0; i < len(brokers); i++ { + select { + case brokerApiVersions := <-ch: + updateClusterApiVersions(&clusterApiVersions, brokerApiVersions) + case err := <-errCh: + errs = append(errs, err) + } } - resp, err := broker.ApiVersions(&sarama.ApiVersionsRequest{}) - if err != nil { - log.Printf("[ERROR] Unable to populate supported API versions. %s", err) - return err + if len(errs) != 0 { + return errors.New(sarama.MultiError{Errors: &errs}.PrettyError()) } - m := map[int]int{} - for _, v := range resp.ApiVersions { - log.Printf("[TRACE] API key %d. Min %d, Max %d", v.ApiKey, v.MinVersion, v.MaxVersion) - m[int(v.ApiKey)] = int(v.MaxVersion) + c.supportedAPIs = make(map[int]int, len(clusterApiVersions)) + for apiKey, versionMinMax := range clusterApiVersions { + versionMin := versionMinMax[0] + versionMax := versionMinMax[1] + + if versionMax >= versionMin { + c.supportedAPIs[apiKey] = versionMax + } + + // versionMax will be less than versionMin only when + // two or more brokers have disjoint version + // intervals...which means the api is not supported + // cluster-wide } - c.supportedAPIs = m return nil } +func apiVersionsFromBroker(broker *sarama.Broker, config *sarama.Config, ch chan <- []*sarama.ApiVersionsResponseBlock, errCh chan <- error) { + resp, err := rawApiVersionsRequest(broker, config) + + if err != nil { + errCh <- err + } else if (resp.Err != sarama.ErrNoError) { + errCh <- errors.New(resp.Err.Error()) + } else { + ch <- resp.ApiVersions + } +} + +func rawApiVersionsRequest(broker *sarama.Broker, config *sarama.Config) (*sarama.ApiVersionsResponse, error) { + if err := broker.Open(config); err != nil && err != sarama.ErrAlreadyConnected { + return nil, err + } + + defer func() { + if err := broker.Close(); err != nil && err != sarama.ErrNotConnected { + log.Fatal(err) + } + }() + + return broker.ApiVersions(&sarama.ApiVersionsRequest{}) +} + +func updateClusterApiVersions(clusterApiVersions *map[int][2]int, brokerApiVersions []*sarama.ApiVersionsResponseBlock) { + cluster := *clusterApiVersions + + for _, apiBlock := range brokerApiVersions { + apiKey := int(apiBlock.ApiKey) + brokerMin := int(apiBlock.MinVersion) + brokerMax := int(apiBlock.MaxVersion) + + clusterMinMax, exists := cluster[apiKey] + if !exists { + cluster[apiKey] = [2]int{brokerMin, brokerMax} + } else { + // shrink the cluster interval according to + // the broker interval + + clusterMin := clusterMinMax[0] + clusterMax := clusterMinMax[1] + + if brokerMin > clusterMin { + clusterMinMax[0] = brokerMin + } + + if brokerMax < clusterMax { + clusterMinMax[1] = brokerMax + } + + cluster[apiKey] = clusterMinMax + } + } +} + func (c *Client) DeleteTopic(t string) error { broker, err := c.client.Controller() if err != nil { @@ -208,6 +285,157 @@ func (c *Client) AddPartitions(t Topic) error { return err } +func (c *Client) CanAlterReplicationFactor() bool { + _, ok1 := c.supportedAPIs[45] // https://kafka.apache.org/protocol#The_Messages_AlterPartitionReassignments + _, ok2 := c.supportedAPIs[46] // https://kafka.apache.org/protocol#The_Messages_ListPartitionReassignments + + return ok1 && ok2 +} + +func (c *Client) AlterReplicationFactor(t Topic) error { + if err := c.client.RefreshMetadata(); err != nil { + return err + } + + admin, err := sarama.NewClusterAdminFromClient(c.client) + if err != nil { + return err + } + + assignment, err := c.buildAssignment(t) + if err != nil { + return err + } + + return admin.AlterPartitionReassignments(t.Name, *assignment) +} + +func (c *Client) buildAssignment(t Topic) (*[][]int32, error) { + partitions, err := c.client.Partitions(t.Name) + if err != nil { + return nil, err + } + + allReplicas := c.allReplicas() + newRF := t.ReplicationFactor + rand.Seed(time.Now().UnixNano()) + + assignment := make([][]int32, len(partitions)) + for _, p := range partitions { + oldReplicas, err := c.client.Replicas(t.Name, p) + if err != nil { + return &assignment, err + } + + oldRF := int16(len(oldReplicas)) + deltaRF := newRF - oldRF + newReplicas, err := buildNewReplicas(allReplicas, &oldReplicas, deltaRF) + if err != nil { + return &assignment, err + } + + assignment[p] = *newReplicas + } + + return &assignment, nil +} + +func (c *Client) allReplicas() *[]int32 { + brokers := c.client.Brokers() + replicas := make([]int32, 0, len(brokers)) + + for _, b := range brokers { + id := b.ID() + if id != -1 { + replicas = append(replicas, id) + } + } + + return &replicas +} + +func buildNewReplicas(allReplicas *[]int32, usedReplicas *[]int32, deltaRF int16) (*[]int32, error) { + usedCount := int16(len(*usedReplicas)) + + if deltaRF == 0 { + return usedReplicas, nil + } else if deltaRF < 0 { + end := usedCount + deltaRF + if end < 1 { + return nil, errors.New("dropping too many replicas") + } + + head := (*usedReplicas)[:end] + return &head, nil + } else { + extraCount := int16(len(*allReplicas)) - usedCount + if extraCount < deltaRF { + return nil, errors.New("not enough brokers") + } + + unusedReplicas := *findUnusedReplicas(allReplicas, usedReplicas, extraCount) + newReplicas := *usedReplicas + for i := int16(0); i < deltaRF; i++ { + j := rand.Intn(len(unusedReplicas)) + newReplicas = append(newReplicas, unusedReplicas[j]) + unusedReplicas[j] = unusedReplicas[len(unusedReplicas)-1] + unusedReplicas = unusedReplicas[:len(unusedReplicas)-1] + } + + return &newReplicas, nil + } +} + +func findUnusedReplicas(allReplicas *[]int32, usedReplicas *[]int32, extraCount int16) *[]int32 { + usedMap := make(map[int32]bool, len(*usedReplicas)) + for _, r := range *usedReplicas { + usedMap[r] = true + } + + unusedReplicas := make([]int32, 0, extraCount) + for _, r := range *allReplicas { + _, exists := usedMap[r] + if !exists { + unusedReplicas = append(unusedReplicas, r) + } + } + + return &unusedReplicas +} + +func (c *Client) IsReplicationFactorUpdating(topic string) (bool, error) { + if err := c.client.RefreshMetadata(); err != nil { + return false, err + } + + partitions, err := c.client.Partitions(topic) + if err != nil { + return false, err + } + + admin, err := sarama.NewClusterAdminFromClient(c.client) + if err != nil { + return false, err + } + + statusMap, err := admin.ListPartitionReassignments(topic, partitions) + if err != nil { + return false, err + } + + for _, status := range statusMap[topic] { + if isPartitionRFChanging(status) { + return true, nil + } + } + + return false, nil +} + +func isPartitionRFChanging(status *sarama.PartitionReplicaReassignmentsStatus) bool { + return len(status.AddingReplicas) != 0 || len(status.RemovingReplicas) != 0 +} + func (client *Client) ReadTopic(name string) (Topic, error) { c := client.client diff --git a/kafka/config.go b/kafka/config.go index 25654dea..8d818582 100644 --- a/kafka/config.go +++ b/kafka/config.go @@ -28,7 +28,7 @@ type Config struct { func (c *Config) newKafkaConfig() (*sarama.Config, error) { kafkaConfig := sarama.NewConfig() - kafkaConfig.Version = sarama.V2_1_0_0 + kafkaConfig.Version = sarama.V2_4_0_0 kafkaConfig.ClientID = "terraform-provider-kafka" kafkaConfig.Admin.Timeout = time.Duration(c.Timeout) * time.Second diff --git a/kafka/config_test.go b/kafka/config_test.go index 6badaca0..b1f9bfe5 100644 --- a/kafka/config_test.go +++ b/kafka/config_test.go @@ -38,18 +38,18 @@ func Test_newTLSConfig(t *testing.T) { { name: "encrypted key files", args: args{ - clientCert: "../secrets/terraform-cert.pem", - clientKey: "../secrets/terraform-with-passphrase.pem", + clientCert: "../secrets/client.pem", + clientKey: "../secrets/client.key", caCert: "../secrets/ca.crt", - clientKeyPassphrase: "confluent", + clientKeyPassphrase: "test-pass", }, wantErr: false, }, { name: "unencrypted key files", args: args{ - clientCert: "../secrets/terraform-cert.pem", - clientKey: "../secrets/terraform.pem", + clientCert: "../secrets/client.pem", + clientKey: "../secrets/client-no-password.key", caCert: "../secrets/ca.crt", clientKeyPassphrase: "", }, @@ -58,8 +58,8 @@ func Test_newTLSConfig(t *testing.T) { { name: "unencrypted key files without passphrase", args: args{ - clientCert: "../secrets/terraform-cert.pem", - clientKey: "../secrets/terraform.pem", + clientCert: "../secrets/client.pem", + clientKey: "../secrets/client-no-password.key", caCert: "../secrets/ca.crt", clientKeyPassphrase: "wrong", }, @@ -68,8 +68,8 @@ func Test_newTLSConfig(t *testing.T) { { name: "unencrypted key content without passphrase", args: args{ - clientCert: loadFile(t, "../secrets/terraform-cert.pem"), - clientKey: loadFile(t, "../secrets/terraform.pem"), + clientCert: loadFile(t, "../secrets/client.pem"), + clientKey: loadFile(t, "../secrets/client-no-password.key"), caCert: loadFile(t, "../secrets/ca.crt"), clientKeyPassphrase: "", }, @@ -78,28 +78,28 @@ func Test_newTLSConfig(t *testing.T) { { name: "encrypted key content with passphrase", args: args{ - clientCert: loadFile(t, "../secrets/terraform-cert.pem"), - clientKey: loadFile(t, "../secrets/terraform-with-passphrase.pem"), + clientCert: loadFile(t, "../secrets/client.pem"), + clientKey: loadFile(t, "../secrets/client.key"), caCert: loadFile(t, "../secrets/ca.crt"), - clientKeyPassphrase: "confluent", + clientKeyPassphrase: "test-pass", }, wantErr: false, }, { name: "encrypted key content with passphrase and mixed file/content load", args: args{ - clientCert: loadFile(t, "../secrets/terraform-cert.pem"), - clientKey: "../secrets/terraform-with-passphrase.pem", + clientCert: loadFile(t, "../secrets/client.pem"), + clientKey: "../secrets/client.key", caCert: "../secrets/ca.crt", - clientKeyPassphrase: "confluent", + clientKeyPassphrase: "test-pass", }, wantErr: false, }, { name: "encrypted cert content without passphrase and mixed file/content load", args: args{ - clientCert: loadFile(t, "../secrets/terraform-cert.pem"), - clientKey: "../secrets/terraform-with-passphrase.pem", + clientCert: loadFile(t, "../secrets/client.pem"), + clientKey: "../secrets/client.key", caCert: "../secrets/ca.crt", clientKeyPassphrase: "", }, diff --git a/kafka/lazy_client.go b/kafka/lazy_client.go index fcab7a10..c65a33f5 100644 --- a/kafka/lazy_client.go +++ b/kafka/lazy_client.go @@ -97,6 +97,30 @@ func (c *LazyClient) AddPartitions(t Topic) error { return c.inner.AddPartitions(t) } +func (c *LazyClient) CanAlterReplicationFactor() (bool, error) { + err := c.init() + if err != nil { + return false, err + } + return c.inner.CanAlterReplicationFactor(), nil +} + +func (c *LazyClient) AlterReplicationFactor(t Topic) error { + err := c.init() + if err != nil { + return err + } + return c.inner.AlterReplicationFactor(t) +} + +func (c *LazyClient) IsReplicationFactorUpdating(topic string) (bool, error) { + err := c.init() + if err != nil { + return false, err + } + return c.inner.IsReplicationFactorUpdating(topic) +} + func (c *LazyClient) CreateACL(s StringlyTypedACL) error { err := c.init() if err != nil { diff --git a/kafka/provider_test.go b/kafka/provider_test.go index f15eec6a..49fdf72b 100644 --- a/kafka/provider_test.go +++ b/kafka/provider_test.go @@ -11,6 +11,7 @@ import ( ) var testProvider *schema.Provider +var testBootstrapServers []string = bootstrapServersFromEnv() func TestProvider(t *testing.T) { if err := Provider().(*schema.Provider).InternalValidate(); err != nil { @@ -33,17 +34,9 @@ func accProvider() map[string]terraform.ResourceProvider { log.Println("[INFO] Setting up override for a provider") provider := Provider().(*schema.Provider) - bs := strings.Split(os.Getenv("KAFKA_BOOTSTRAP_SERVER"), ",") - if len(bs) == 0 { - bs = []string{"localhost:9092"} - } - bootstrapServers := []interface{}{} - - for _, v := range bs { - if v != "" { - bootstrapServers = append(bootstrapServers, v) - } + for _, bs := range testBootstrapServers { + bootstrapServers = append(bootstrapServers, bs) } raw := map[string]interface{}{ @@ -61,3 +54,34 @@ func accProvider() map[string]terraform.ResourceProvider { "kafka": provider, } } + +func bootstrapServersFromEnv() []string { + fromEnv := strings.Split(os.Getenv("KAFKA_BOOTSTRAP_SERVER"), ",") + fromEnv = nonEmptyAndTrimmed(fromEnv) + + if len(fromEnv) == 0 { + fromEnv = []string{"localhost:9092"} + } + + bootstrapServers := make([]string, 0) + for _, bs := range fromEnv { + if bs != "" { + bootstrapServers = append(bootstrapServers, bs) + } + } + + return bootstrapServers +} + +func nonEmptyAndTrimmed(bootstrapServers []string) []string { + wellFormed := make([]string, 0) + + for _, bs := range bootstrapServers { + trimmed := strings.TrimSpace(bs) + if trimmed != "" { + wellFormed = append(wellFormed, trimmed) + } + } + + return wellFormed +} diff --git a/kafka/resource_kafka_acl_test.go b/kafka/resource_kafka_acl_test.go index 475227a8..c33f92cf 100644 --- a/kafka/resource_kafka_acl_test.go +++ b/kafka/resource_kafka_acl_test.go @@ -17,6 +17,7 @@ func TestAcc_ACLCreateAndUpdate(t *testing.T) { t.Fatal(err) } aclResourceName := fmt.Sprintf("syslog-%s", u) + bs := testBootstrapServers[0] r.Test(t, r.TestCase{ Providers: accProvider(), @@ -25,18 +26,18 @@ func TestAcc_ACLCreateAndUpdate(t *testing.T) { CheckDestroy: func(s *terraform.State) error { return testAccCheckAclDestroy(aclResourceName) }, Steps: []r.TestStep{ { - Config: fmt.Sprintf(testResourceACL_initialConfig, aclResourceName), + Config: fmt.Sprintf(testResourceACL_initialConfig, bs, aclResourceName), Check: testResourceACL_initialCheck, }, { - Config: fmt.Sprintf(testResourceACL_updateConfig, aclResourceName), + Config: fmt.Sprintf(testResourceACL_updateConfig, bs, aclResourceName), Check: testResourceACL_updateCheck, }, { ResourceName: "kafka_acl.test", ImportState: true, ImportStateVerify: true, - Config: fmt.Sprintf(testResourceACL_updateConfig, aclResourceName), + Config: fmt.Sprintf(testResourceACL_updateConfig, bs, aclResourceName), }, }, }) @@ -171,10 +172,10 @@ func testResourceACL_updateCheck(s *terraform.State) error { //lintignore:AT004 const testResourceACL_initialConfig = ` provider "kafka" { - bootstrap_servers = ["localhost:9092"] + bootstrap_servers = ["%s"] ca_cert = file("../secrets/ca.crt") - client_cert = file("../secrets/terraform-cert.pem") - client_key = file("../secrets/terraform.pem") + client_cert = file("../secrets/client.pem") + client_key = file("../secrets/client.key") } resource "kafka_acl" "test" { @@ -191,10 +192,10 @@ resource "kafka_acl" "test" { //lintignore:AT004 const testResourceACL_updateConfig = ` provider "kafka" { - bootstrap_servers = ["localhost:9092"] + bootstrap_servers = ["%s"] ca_cert = file("../secrets/ca.crt") - client_cert = file("../secrets/terraform-cert.pem") - client_key = file("../secrets/terraform.pem") + client_cert = file("../secrets/client.pem") + client_key = file("../secrets/client.key") } resource "kafka_acl" "test" { diff --git a/kafka/resource_kafka_topic.go b/kafka/resource_kafka_topic.go index 46b9835b..6820f9bc 100644 --- a/kafka/resource_kafka_topic.go +++ b/kafka/resource_kafka_topic.go @@ -26,7 +26,7 @@ func kafkaTopicResource() *schema.Resource { Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, - CustomizeDiff: customPartitionDiff, + CustomizeDiff: customDiff, Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, @@ -43,7 +43,7 @@ func kafkaTopicResource() *schema.Resource { "replication_factor": { Type: schema.TypeInt, Required: true, - ForceNew: true, + ForceNew: false, Description: "Number of replicas.", ValidateFunc: positiveValue, }, @@ -67,18 +67,62 @@ func topicCreate(d *schema.ResourceData, meta interface{}) error { return err } + stateConf := &resource.StateChangeConf{ + Pending: []string{"Pending"}, + Target: []string{"Created"}, + Refresh: topicCreateFunc(c, t), + Timeout: time.Duration(c.Config.Timeout) * time.Second, + Delay: 1 * time.Second, + PollInterval: 2 * time.Second, + } + + if _, err := stateConf.WaitForState(); err != nil { + return fmt.Errorf("error waiting for topic (%s) to be created: %s", t.Name, err) + } + d.SetId(t.Name) return nil } +func topicCreateFunc(client *LazyClient, t Topic) resource.StateRefreshFunc { + return func() (result interface{}, s string, err error) { + topic, err := client.ReadTopic(t.Name) + switch e := err.(type) { + case TopicMissingError: + return topic, "Pending", nil + case nil: + return topic, "Created", nil + default: + return topic, "Error", e + } + } +} + func topicUpdate(d *schema.ResourceData, meta interface{}) error { c := meta.(*LazyClient) t := metaToTopic(d, meta) - err := c.UpdateTopic(t) - if err != nil { + if err := c.UpdateTopic(t); err != nil { return err } + + // update replica count of existing partitions before adding new ones + if d.HasChange("replication_factor") { + oi, ni := d.GetChange("replication_factor") + oldRF := oi.(int) + newRF := ni.(int) + log.Printf("[INFO] Updating replication_factor from %d to %d", oldRF, newRF) + t.ReplicationFactor = int16(newRF) + + if err := c.AlterReplicationFactor(t); err != nil { + return err + } + + if err := waitForRFUpdate(c, d.Id()); err != nil { + return err + } + } + if d.HasChange("partitions") { // update should only be called when we're increasing partitions oi, ni := d.GetChange("partitions") @@ -86,32 +130,70 @@ func topicUpdate(d *schema.ResourceData, meta interface{}) error { newPartitions := ni.(int) log.Printf("[INFO] Updating partitions from %d to %d", oldPartitions, newPartitions) t.Partitions = int32(newPartitions) - err = c.AddPartitions(t) - if err != nil { + + if err := c.AddPartitions(t); err != nil { return err } } - timeout := time.Duration(c.Config.Timeout) * time.Second + if err := waitForTopicRefresh(c, d.Id(), t); err != nil { + return err + } + + return nil +} + +func waitForRFUpdate(client *LazyClient, topic string) error { + refresh := func() (interface{}, string, error) { + isRFUpdating, err := client.IsReplicationFactorUpdating(topic) + if err != nil { + return nil, "Error", err + } else if isRFUpdating { + return nil, "Updating", nil + } else { + return "not-nil", "Ready", nil + } + } + + timeout := time.Duration(client.Config.Timeout) * time.Second stateConf := &resource.StateChangeConf{ Pending: []string{"Updating"}, Target: []string{"Ready"}, - Refresh: topicRefreshFunc(c, d.Id(), t), + Refresh: refresh, Timeout: timeout, Delay: 1 * time.Second, PollInterval: 1 * time.Second, MinTimeout: 2 * time.Second, } - _, err = stateConf.WaitForState() + if _, err := stateConf.WaitForState(); err != nil { + return fmt.Errorf( + "Error waiting for topic (%s) replication_factor to update: %s", + topic, err) + } - if err != nil { + return nil +} + +func waitForTopicRefresh(client *LazyClient, topic string, expected Topic) error { + timeout := time.Duration(client.Config.Timeout) * time.Second + stateConf := &resource.StateChangeConf{ + Pending: []string{"Updating"}, + Target: []string{"Ready"}, + Refresh: topicRefreshFunc(client, topic, expected), + Timeout: timeout, + Delay: 1 * time.Second, + PollInterval: 1 * time.Second, + MinTimeout: 2 * time.Second, + } + + if _, err := stateConf.WaitForState(); err != nil { return fmt.Errorf( "Error waiting for topic (%s) to become ready: %s", - d.Id(), err) + topic, err) } - return err + return nil } func topicRefreshFunc(client *LazyClient, topic string, expected Topic) resource.StateRefreshFunc { @@ -201,8 +283,10 @@ func topicRead(d *schema.ResourceData, meta interface{}) error { return errSet.err } -func customPartitionDiff(diff *schema.ResourceDiff, v interface{}) (err error) { +func customDiff(diff *schema.ResourceDiff, v interface{}) error { log.Printf("[INFO] Checking the diff!") + client := v.(*LazyClient) + if diff.HasChange("partitions") { log.Printf("[INFO] Partitions have changed!") o, n := diff.GetChange("partitions") @@ -211,9 +295,25 @@ func customPartitionDiff(diff *schema.ResourceDiff, v interface{}) (err error) { log.Printf("Partitions is changing from %d to %d", oi, ni) if ni < oi { log.Printf("Partitions decreased from %d to %d. Forcing new resource", oi, ni) - err = diff.ForceNew("partitions") + if err := diff.ForceNew("partitions"); err != nil { + return err + } + } + } + + if diff.HasChange("replication_factor") { + canAlterRF, err := client.CanAlterReplicationFactor() + if err != nil { + return err } + if !canAlterRF { + log.Println("[INFO] Need kafka >= 2.4.0 to update replication_factor in-place") + if err := diff.ForceNew("replication_factor"); err != nil { + return err + } + } } - return err + + return nil } diff --git a/kafka/resource_kafka_topic_test.go b/kafka/resource_kafka_topic_test.go index 779554f4..d01c85d4 100644 --- a/kafka/resource_kafka_topic_test.go +++ b/kafka/resource_kafka_topic_test.go @@ -2,11 +2,16 @@ package kafka import ( "fmt" + "log" "testing" + "time" + "strconv" uuid "github.com/hashicorp/go-uuid" r "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" + + "github.com/Shopify/sarama" ) func TestAcc_BasicTopic(t *testing.T) { @@ -15,13 +20,14 @@ func TestAcc_BasicTopic(t *testing.T) { t.Fatal(err) } topicName := fmt.Sprintf("syslog-%s", u) + bs := testBootstrapServers[0] r.Test(t, r.TestCase{ Providers: accProvider(), PreCheck: func() { testAccPreCheck(t) }, CheckDestroy: testAccCheckTopicDestroy, Steps: []r.TestStep{ { - Config: fmt.Sprintf(testResourceTopic_noConfig, topicName), + Config: fmt.Sprintf(testResourceTopic_noConfig, bs, topicName), Check: testResourceTopic_noConfigCheck, }, }, @@ -34,6 +40,7 @@ func TestAcc_TopicConfigUpdate(t *testing.T) { t.Fatal(err) } topicName := fmt.Sprintf("syslog-%s", u) + bs := testBootstrapServers[0] r.Test(t, r.TestCase{ Providers: accProvider(), @@ -41,11 +48,11 @@ func TestAcc_TopicConfigUpdate(t *testing.T) { CheckDestroy: testAccCheckTopicDestroy, Steps: []r.TestStep{ { - Config: fmt.Sprintf(testResourceTopic_initialConfig, topicName), + Config: fmt.Sprintf(testResourceTopic_initialConfig, bs, topicName), Check: testResourceTopic_initialCheck, }, { - Config: fmt.Sprintf(testResourceTopic_updateConfig, topicName), + Config: fmt.Sprintf(testResourceTopic_updateConfig, bs, topicName), Check: testResourceTopic_updateCheck, }, }, @@ -85,6 +92,7 @@ func TestAcc_TopicUpdatePartitions(t *testing.T) { t.Fatal(err) } topicName := fmt.Sprintf("syslog-%s", u) + bs := testBootstrapServers[0] r.Test(t, r.TestCase{ Providers: accProvider(), @@ -92,17 +100,77 @@ func TestAcc_TopicUpdatePartitions(t *testing.T) { CheckDestroy: testAccCheckTopicDestroy, Steps: []r.TestStep{ { - Config: fmt.Sprintf(testResourceTopic_initialConfig, topicName), + Config: fmt.Sprintf(testResourceTopic_initialConfig, bs, topicName), Check: testResourceTopic_initialCheck, }, { - Config: fmt.Sprintf(testResourceTopic_updatePartitions, topicName), + Config: fmt.Sprintf(testResourceTopic_updatePartitions, bs, topicName), Check: testResourceTopic_updatePartitionsCheck, }, }, }) } +func TestAcc_TopicAlterReplicationFactor(t *testing.T) { + u, err := uuid.GenerateUUID() + if err != nil { + t.Fatal(err) + } + topicName := fmt.Sprintf("syslog-%s", u) + bs := testBootstrapServers[0] + + keyEncoder := sarama.StringEncoder("same key -> same partition -> same ordering") + messages := []*sarama.ProducerMessage{ + &sarama.ProducerMessage{ + Topic: topicName, + Key: keyEncoder, + Value: sarama.StringEncoder("Krusty"), + }, + &sarama.ProducerMessage{ + Topic: topicName, + Key: keyEncoder, + Value: sarama.StringEncoder("Krab"), + }, + &sarama.ProducerMessage{ + Topic: topicName, + Key: keyEncoder, + Value: sarama.StringEncoder("Pizza"), + }, + } + + r.Test(t, r.TestCase{ + Providers: accProvider(), + PreCheck: func() { testAccPreCheck(t) }, + CheckDestroy: testAccCheckTopicDestroy, + Steps: []r.TestStep{ + { + Config: fmt.Sprintf(testResourceTopic_updateRF, bs, topicName, 1, 7), + Check: r.ComposeTestCheckFunc( + testResourceTopic_produceMessages(messages), + testResourceTopic_initialCheck), + }, + { + Config: fmt.Sprintf(testResourceTopic_updateRF, bs, topicName, 3, 7), + Check: r.ComposeTestCheckFunc( + testResourceTopic_updateRFCheck, + testResourceTopic_checkSameMessages(messages)), + }, + { + Config: fmt.Sprintf(testResourceTopic_updateRF, bs, topicName, 2, 8), + Check: r.ComposeTestCheckFunc( + testResourceTopic_updateRFCheck, + testResourceTopic_checkSameMessages(messages)), + }, + { + Config: fmt.Sprintf(testResourceTopic_updateRF, bs, topicName, 1, 10), + Check: r.ComposeTestCheckFunc( + testResourceTopic_updateRFCheck, + testResourceTopic_checkSameMessages(messages)), + }, + }, + }) +} + func testResourceTopic_noConfigCheck(s *terraform.State) error { resourceState := s.Modules[0].Resources["kafka_topic.test"] if resourceState == nil { @@ -171,6 +239,36 @@ func testResourceTopic_initialCheck(s *terraform.State) error { return nil } +func testResourceTopic_produceMessages(messages []*sarama.ProducerMessage) r.TestCheckFunc { + return func(s *terraform.State) error { + config := testProvider.Meta().(*LazyClient).inner.config + kafkaConfig, err := config.newKafkaConfig() + if err != nil { + return err + } + kafkaConfig.Producer.Return.Errors = true + kafkaConfig.Producer.Return.Successes = true + kafkaConfig.Producer.RequiredAcks = sarama.WaitForAll + + producer, err := sarama.NewSyncProducer(*config.BootstrapServers, kafkaConfig) + if err != nil { + return err + } + + defer func() { + if err := producer.Close(); err != nil { + log.Fatalln(err) + } + }() + + if err := producer.SendMessages(messages); err != nil { + return err + } + + return nil + } +} + func testResourceTopic_updateCheck(s *terraform.State) error { resourceState := s.Modules[0].Resources["kafka_topic.test"] instanceState := resourceState.Primary @@ -219,10 +317,140 @@ func testResourceTopic_updatePartitionsCheck(s *terraform.State) error { return nil } +func testResourceTopic_updateRFCheck(s *terraform.State) error { + resourceState := s.Modules[0].Resources["kafka_topic.test"] + instanceState := resourceState.Primary + client := testProvider.Meta().(*LazyClient) + topicName := instanceState.Attributes["name"] + + parsed, err := strconv.ParseInt(instanceState.Attributes["replication_factor"], 10, 16) + if err != nil { + return err + } + expectedRF := int16(parsed) + + parsed, err = strconv.ParseInt(instanceState.Attributes["partitions"], 10, 32) + if err != nil { + return err + } + expectedPartitions := int32(parsed) + + topic, err := client.ReadTopic(topicName) + if err != nil { + return err + } + + if actual := topic.ReplicationFactor; actual != expectedRF { + return fmt.Errorf("expected replication.factor of %d, but got %d", expectedRF, actual) + } + + if actual := topic.Partitions; actual != expectedPartitions { + return fmt.Errorf("expected %d partitions, but got %d", expectedPartitions, actual) + } + + return nil +} + +func testResourceTopic_checkSameMessages(producedMessages []*sarama.ProducerMessage) r.TestCheckFunc { + return func(s *terraform.State) error { + resourceState := s.Modules[0].Resources["kafka_topic.test"] + instanceState := resourceState.Primary + client := testProvider.Meta().(*LazyClient) + topicName := instanceState.Attributes["name"] + + consumer, err := sarama.NewConsumerFromClient(client.inner.client) + if err != nil { + return err + } + + defer func() { + if err := consumer.Close(); err != nil { + log.Fatalln(err) + } + }() + + // all messages are produced to the same partition + partition := producedMessages[0].Partition + maxCount := len(producedMessages) + consumedMessages, err := testConsumePartition(consumer, topicName, partition, maxCount) + if err != nil { + return err + } + + return testSameMessages(producedMessages, consumedMessages) + } +} + +func testConsumePartition(consumer sarama.Consumer, topic string, partition int32, maxCount int) ([]*sarama.ConsumerMessage, error) { + consumedMessages := make([]*sarama.ConsumerMessage, 0, maxCount) + + partitionConsumer, err := consumer.ConsumePartition(topic, partition, sarama.OffsetOldest) + if err != nil { + return consumedMessages, err + } + + defer func() { + if err := partitionConsumer.Close(); err != nil { + log.Fatalln(err) + } + }() + + for len(consumedMessages) < maxCount { + select { + case message := <-partitionConsumer.Messages(): + consumedMessages = append(consumedMessages, message) + case <- time.After(10 * time.Second): + return consumedMessages, nil + } + } + + return consumedMessages, nil +} + +func testSameMessages(produced []*sarama.ProducerMessage, consumed []*sarama.ConsumerMessage) error { + plen := len(produced) + clen := len(consumed) + if plen != clen { + return fmt.Errorf("produced and consumed message counts differ, %d != %d", plen, clen) + } + + for i, pm := range produced { + cm := consumed[i] + if err := testMessageEqual(pm, cm); err != nil { + return err + } + } + + return nil +} + +func testMessageEqual(pm *sarama.ProducerMessage, cm *sarama.ConsumerMessage) error { + if pm.Partition != cm.Partition { + return fmt.Errorf("different partitions: %d != %d", pm.Partition, cm.Partition) + } + + if pm.Offset != cm.Offset { + return fmt.Errorf("different offsets: %d != %d", pm.Offset, cm.Offset) + } + + pmBytes, err := pm.Value.Encode() + if err != nil { + return err + } + + pmValue := string(pmBytes) + cmValue := string(cm.Value) + if pmValue != cmValue { + return fmt.Errorf("different values: %v != %v", pmValue, cmValue) + } + + return nil +} + //lintignore:AT004 const testResourceTopic_noConfig = ` provider "kafka" { - bootstrap_servers = ["localhost:9092"] + bootstrap_servers = ["%s"] } resource "kafka_topic" "test" { @@ -235,7 +463,7 @@ resource "kafka_topic" "test" { //lintignore:AT004 const testResourceTopic_initialConfig = ` provider "kafka" { - bootstrap_servers = ["localhost:9092"] + bootstrap_servers = ["%s"] } resource "kafka_topic" "test" { @@ -253,7 +481,7 @@ resource "kafka_topic" "test" { //lintignore:AT004 const testResourceTopic_updateConfig = ` provider "kafka" { - bootstrap_servers = ["localhost:9092"] + bootstrap_servers = ["%s"] } resource "kafka_topic" "test" { @@ -271,7 +499,7 @@ resource "kafka_topic" "test" { //lintignore:AT004 const testResourceTopic_updatePartitions = ` provider "kafka" { - bootstrap_servers = ["localhost:9092"] + bootstrap_servers = ["%s"] } resource "kafka_topic" "test" { @@ -285,3 +513,21 @@ resource "kafka_topic" "test" { } } ` + +//lintignore:AT004 +const testResourceTopic_updateRF = ` +provider "kafka" { + bootstrap_servers = ["%s"] +} + +resource "kafka_topic" "test" { + name = "%s" + replication_factor = %d + partitions = %d + + config = { + "retention.ms" = "11111" + "segment.ms" = "22222" + } +} +` diff --git a/secrets/broker1.csr b/secrets/broker1.csr deleted file mode 100644 index 6144da09..00000000 --- a/secrets/broker1.csr +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN NEW CERTIFICATE REQUEST----- -MIIC2TCCAcECAQAwZDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNhMREwDwYDVQQH -EwhQYWxvQWx0bzESMBAGA1UEChMJQ09ORkxVRU5UMQ0wCwYDVQQLEwRURVNUMRIw -EAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCBmb+hxpM7wbzPgbDRY9iCisC0C5mOSzfZddCF+/BA0FYtxRubrdpSXkQ18tSX -Va5L/iRJo38pkgbcvmbTN1t+/cpXS97z4mxDkYeeBwaldpVJ8s3ByUt/OHndcAzU -dDtrfCdNi6uuhyDWQJvHph8V6ss0CCCTVCbIxmYi83oBLiWM3OjTjj6Au2hPabyh -CEXXtRKvgE0UJjj4OydSg0zhH09kSERnG0aTjfKXxDqs8v9x8QYOwZlZTrLQt3RM -jM6XskjvklYOJnZIs6ABFu3poVzAezbRyRRCkYjsrt+8QCCd59dBKMkvLfma/cIr -QhiQzvy8WyvORzU7XqGvltlNAgMBAAGgMDAuBgkqhkiG9w0BCQ4xITAfMB0GA1Ud -DgQWBBQL5gn1XNaQL3b2srXiJlENKzlVVDANBgkqhkiG9w0BAQsFAAOCAQEAKyxa -f9bOohyZ389juEDuvXKowNicZ5NxMtPC++Yr8KsWpfFOABGV1gFp82GhaKYDKElu -sHk/L7ZkD5Ny5iUGuBfJas3fxPlGU3f00VpywxQfP9MJLuotBouPfsRJ1eRvzYiS -rp5Iv4hH4zWnVrx0r7q2psHRVbyWYvMu5oNj56TD/JzYT36ehM26+Avhl+2xHoFv -jxOQPJ27RFbwCqB0PWyq8IWSgxfHh55+4MiVokgrN5FEV2lFhuqyWG1WZSH1Hn8d -dEI1Q6Zj7yu+6u03/HO2XwbVkl8XjQO9nyR3tvZKIwd929cDPHnOkTidwmmp0WlZ -PYy5RNIqhuuyYAYqGA== ------END NEW CERTIFICATE REQUEST----- diff --git a/secrets/broker1_keystore_creds b/secrets/broker1_keystore_creds deleted file mode 100644 index 23212273..00000000 --- a/secrets/broker1_keystore_creds +++ /dev/null @@ -1 +0,0 @@ -confluent diff --git a/secrets/broker1_sslkey_creds b/secrets/broker1_sslkey_creds deleted file mode 100644 index 23212273..00000000 --- a/secrets/broker1_sslkey_creds +++ /dev/null @@ -1 +0,0 @@ -confluent diff --git a/secrets/broker1_truststore_creds b/secrets/broker1_truststore_creds deleted file mode 100644 index 23212273..00000000 --- a/secrets/broker1_truststore_creds +++ /dev/null @@ -1 +0,0 @@ -confluent diff --git a/secrets/ca.crt b/secrets/ca.crt index 623f1789..bdf0d3c6 100644 --- a/secrets/ca.crt +++ b/secrets/ca.crt @@ -1,20 +1,34 @@ -----BEGIN CERTIFICATE----- -MIIDQjCCAioCCQDpNW3UqtXznzANBgkqhkiG9w0BAQsFADBjMR4wHAYDVQQDDBVj -YTEudGVzdC5jb25mbHVlbnQuaW8xDTALBgNVBAsMBFRFU1QxEjAQBgNVBAoMCUNP -TkZMVUVOVDERMA8GA1UEBwwIUGFsb0FsdG8xCzAJBgNVBAYTAlVTMB4XDTIwMTEx -NDE4MjgxMFoXDTIxMTExNDE4MjgxMFowYzEeMBwGA1UEAwwVY2ExLnRlc3QuY29u -Zmx1ZW50LmlvMQ0wCwYDVQQLDARURVNUMRIwEAYDVQQKDAlDT05GTFVFTlQxETAP -BgNVBAcMCFBhbG9BbHRvMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAMmXcVRjy5WhYxs8J10czqzbtYsvl62bLdBOiAvPkTcl/kVj -ZUAx8T6cp4QNmy3Ud2eCsG00OYOmmk5GJgyth6NOyJw3OcmgdMRadUNstqnsJTH3 -W+d7XRBwGgdWPgZBRWpfCL4Dnf2CKrvvXv3v6on6zZqpjFewwfSJ7MI5zY4Jr4DV -M5JvVJZqGk2SyEHdpJXKpg8uHW81davRXcF/A4NN2AcF9dAWIh1I4oOsjbsxYzl4 -h8w2lBb58sfYRx1l8hVYffp4aOBDvjPczHj9P4LcaLRuqblUY25nfZH3Dir9erf2 -pRKHKonj6dJpsdH+DEhh1c/+9ssdPfrmrLv5PZ8CAwEAATANBgkqhkiG9w0BAQsF -AAOCAQEAUHms+iGj9r0GaAg5LHN/Y++BWg7VQ7Ky0SNzNTfoAoagXDpTwL55RImp -wPazvZmazc0mV641r1fKyWrWO4VivZ1FSc+WyAeM0B8PQld5rKUW0fc/WCOvRizP -8oTv0HwGlRqSGtZR1U04J63dLc/pjh7/FU9GVtqDjXGIUL58WwFxwR2n36Hmri5V -dyMrIkplPRnJgyo7PKUa9EeUZVnEccYSb7EiRqX86grXvNHbDiGeav00NYEvsWNO -BQieyJPY6RLKD/z/1prBGjFAVffVBX1tQoEOovBaP/Lv9NFFdGE8pB19xTzPT7g6 -rkvBfIq0SrHoRcqFdCdyA/Gv7XqbUg== +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 +ZOTSpLc= -----END CERTIFICATE----- diff --git a/secrets/ca.key b/secrets/ca.key index e692f525..45c5703e 100644 --- a/secrets/ca.key +++ b/secrets/ca.key @@ -1,30 +1,54 @@ -----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIUd4vX+VezgUCAggA -MB0GCWCGSAFlAwQBKgQQXQzSFRBfV7l4JHSDM6dVyASCBNAMfQXS9NeLpqNyvlhx -p+usW2QCONh3ZU2yzUvd8yBh0EK8ofTLgQBO44bzUOn1MN46uXZaYr/dqNO5DB5Z -K979F2A1Vi380uhFwGmMUaGayNpYlWgIV9fDS9tLv+Tnnbh35QGmHi30OTJoeC42 -JdOJDIhVyhUe50fm96GWDOhky+71RXKwwUyR8cF87t8VzcaT54jeLlRPbVLUlf6z -2AeNRxLzdwkjk8YfSc6wleD0B2y2yNySx//Ea2gOmqTvVtEZPEeCrkFZW9Q1AKDl -23KlNUJJOD3ikk7p+n7rUhLS5HhhcWC8Ij/kSNV2m2BnC5jLeoqp2NhVJINfZfQy -9EfyFELVDHHV9GvNnU+2JhVvBEk5rCiAPh7FX2nXHmxDh9M6Uvkf+Xc49efmEnOr -V6ULZ09TiWK+37jgR/o83xvxMEohg0tiT6DgZFfdDK3UbCs+ah/ShpJlbFlQaAIq -JrbBz1V+7uFUxwkGcscjiaVtWNO+KsCq/NvzOj35l4UAk+X8BI/K1uslYNsfiy0R -OOdSmGkxEqWtbdIxcME0GW7PQR3Mn+lkd9MoN3dFr763EOFptzMX6A2Y8qM1cKnW -Kdu2WwZdsLYnHKkbOvkiGpUpzERNimPoF0S6gQnq72wbfjVlVclmW+R9AsvTIfoP -kOJ6dWFp597Ch7H//wUoacKNli4+iy/6E1LHMaytPpcVztY0fxPcmH8CJ2H5BrSg -27fHpgjSFRQf8fR+iOOH2Ir4+ogw8BkUWUfjYZf+xt4W5Fe8wa5xrSQH2XIrK4se -bWl6PWm+c/mQ54khDYdGDLxAz8xU0GwquhjrZJsxUhECY2E+Z3Vaz0rPvUUAZq8c -kYKLkTai6RvGdMaBX5+PSQkxb87MMD3pbwvucsxjz6t48B6LwklRdTru3kNVhmr1 -2HwL1sM/N9BWJs53tF5FaJFei+JTGGN2ZIpfAcl1yTzbNRg/KRDh3dm2qpRRuLwZ -JipzaEs2cn4QJmVSdSitKcE8dXm+B15OBsjHTpl77O4+ZzyNxNYlw3WGnMK6G4PX -tgNa5tTXmfkXRsg8aZaeiAHUrUmdsfX0tD31qzZDCuaxF6GtxhimmzAnp3FFsOMH -Hqmjw8+l2XZTaUwdY5IZ0Kk13do6gXmJQpM+2bGt1kbUx7Jvbz3VfUwHKxyuRRNO -cLUhSQAY9SF1gCpl1uKi3MVgWTUKhpUgtqxpXKBE5luqOLzVyFPZ3Wx2xVYvmAB2 -j7n5+jo4PVyWsb60Sql6tgMoOiQtVezphb/6La0E8t/vkACuUkiRKKLluoJUORHi -b8egz9ojZneSABR8ZHEY33DUMzU27elUzqtbjVezpRFk9IGRqWxK/hJRpaPZmKtb -yFwELboDokTQARGDE7cL+s46OpOgwR5v46NJvmDg1WqyKLdjuA2ESKeUo/cFoiOl -tvANl3lgASep4/qtlA9gc5CeBrFL0SwwmWYb8x/oGL+oAAVIR0ISEs7mx0Rn3Qvg -voDaZ6z+fH8GDQ770kXP3zlQV5uwH5W5y2O1F15J263wE/+4Akflh/FklxxNaRWI -yRyekaLWBL39lezjiJvinP8CMlP/RkXKYiTpkOV9tDdNSz+ILrpEvRnEqard8ucx -ic/jxa5j15CgrnISg9IEmU8NXg== +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 +waGVKR7SY09zX7oqcNYh3a3wvwkMN7mk -----END ENCRYPTED PRIVATE KEY----- diff --git a/secrets/client-no-password.key b/secrets/client-no-password.key new file mode 100644 index 00000000..d1a5354a --- /dev/null +++ b/secrets/client-no-password.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/secrets/client.key b/secrets/client.key new file mode 100644 index 00000000..1af46890 --- /dev/null +++ b/secrets/client.key @@ -0,0 +1,54 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,D124E0DE84855C54 + +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 +-----END RSA PRIVATE KEY----- diff --git a/secrets/client.pem b/secrets/client.pem new file mode 100644 index 00000000..9e38d91c --- /dev/null +++ b/secrets/client.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFdzCCA18CFEdiUCsxxqxBy8fLT9cS3v207xUkMA0GCSqGSIb3DQEBCwUAMHgx +CzAJBgNVBAYTAk1IMRUwEwYDVQQIDAxCaWtpbmkgQXRvbGwxFjAUBgNVBAcMDUJp +a2luaSBCb3R0b20xFDASBgNVBAoMC0tydXN0eSBLcmFiMRAwDgYDVQQLDAdLaXRj +aGVuMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMjAxMDE5MTAwMzUxWhcNNDAxMDE0 +MTAwMzUxWjB4MQswCQYDVQQGEwJNSDEVMBMGA1UECAwMQmlraW5pIEF0b2xsMRYw +FAYDVQQHDA1CaWtpbmkgQm90dG9tMRQwEgYDVQQKDAtLcnVzdHkgS3JhYjEQMA4G +A1UECwwHS2l0Y2hlbjESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAvUQFEtq/lC55zH3tS0DDXJKWDTUGR/7emnypWfB0 +av47E6lLRMOnT6TU+YY2uhRygFbjphsDytWgkwkkMWvci4OOkn53GJgvn+JwL9o4 +ypyBRfaJyY3OLC3RUTNhzZotqIpC0pKciJLglTAUHvSjP5ofgCkthmhFZgcM9SKy +x24jYsb2K182JoJ1H8LaMxh8C0pspLZq4sMUud90QkJZVA5EuCrcSozFwu2tk/Y+ +9QSE6v+rtgguQHMNbaHLnE/sqgLstH0hAN15cXfN3bdHip3moN+lPlehMBoRoahP +0DpY0JYrWxn3Vz9R0O1OOIxeGJjfTkcgO4C+IMXbe89sa2pAGpOtnIaWuy7xlz8E +/6FqLfEmtTpe7bRz/IMqA0BYMCpVUVjpcJzYqjEstxtOSAGdXTKGzefGioyWyGQA ++lfiZW72TOJ6SpirzHpjKXw4xcPYKMS86AVEwWGffZC2NpxY7+PHeh+w149FwkZi +LQQjoRfcslhsG+4MWjRAuGEbaeZ2dOqime0eKpZK9J+d6S+JucCwaAnwHMZYVkuK +kIIgmWEPiUi02nRmsyWa9aZ2uhg3DfDAqi8cUENLfZJzVnMbTy2NtZTCKi2e56S8 +F4zjAQ+OvmPbsnrM2IpOCHPJMLBd6fMCoPB+OgTSwAFUzpWMNX4x2myYxuRZS+Ng +7rcCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAjIbV1HquEBoyC7XMVTpHIcZzEZzL +xzC+ShG6K8hxTCvYP4mAvrfPJNgppEHL92tUxK7MuJBXF8DF0QARYl10kKL0d2Vm +liw8ZRDTpLJUufrNj2xAUGe5F030SVq7JQSvH7yDvph34bibjtUyFh1jlDTzYDgD +BJRTPiImOU+VE7BAxxW5lycAb8HnB6XNCsA62F/gUQNjH3BQrkqd8dF79IuvYUIi +zUlA2fQkZ0UC1fCIYsd5CDU+dlMId6cORSk/9oFFVEPFG2SIzQuesfuQjJn0ZcI1 +n07s4Vfmk1QTb+QPyBUg3TBimagXajuSewI8nyUdu+26/K8n/bFOu/D/QmEnS5dV +WwMuazjbytQf+OiDLam1NXpNpZJuwRNf1T3TJB0P/zHk7NBhyOyErU9RwqUIVxf5 +mgABWdFnC3sZMPsZg3omt7ypYXFxChaU89pPJ3vJx647U/jrLhgbEXR7Pbk2V1iD +ZAOfkOL1hFv9BKyCLNYPOIVawsqDMFRILycs/5NorL1ldWz97qxkjstHXmrRuKXT +v8s9SL1B8gmmqwEdVfal4Cx0W3Hw8XeF7z3djO/FrZIxwAMILUmO/w1hXeeWMjhk +JH6qo3Vc/22Ximt5wpLlEFoeAWRPXNpnbmXmJNfBjcXy16qUaNDUbUzywX1O9nK4 +wpHYxtDUZiHJAr4= +-----END CERTIFICATE----- diff --git a/secrets/create-certs.sh b/secrets/create-certs.sh index 1d49b43e..4957ccd5 100755 --- a/secrets/create-certs.sh +++ b/secrets/create-certs.sh @@ -1,132 +1,148 @@ -#!/bin/bash - -set -o nounset \ - -o errexit \ - -o verbose - -echo "Deleting older secrets" -set +e -rm ./*.key ./*.jks ./*.pem ./*.srl ./*.req ./*.crt ./*.csr ./*_creds -set -e - -PASS=confluent - -# Generate CA key -openssl req \ - -new \ - -x509 \ - -keyout ca.key \ - -out ca.crt \ - -days 365 \ - -subj '/CN=ca1.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/S=Ca/C=US' \ - -passin pass:$PASS \ - -passout pass:$PASS - -# Terraform -# Private KEY -openssl genrsa \ - -des3 \ - -passout "pass:$PASS" \ - -out terraform.client.key \ - 1024 - -# Signing Request -openssl req \ - -passin "pass:$PASS" \ - -passout "pass:$PASS" \ - -key terraform.client.key \ - -new \ - -out terraform.client.req \ - -subj '/CN=terraform.test.confluent.io/OU=TEST/O=CONFLUENT/L=PaloAlto/S=Ca/C=US' - -# Signed Key -openssl x509 -req \ - -CA ca.crt \ - -CAkey ca.key \ - -in terraform.client.req \ - -out terraform-cert.pem \ - -days 9999 \ - -CAcreateserial \ - -passin "pass:$PASS" - - -## generate for golang - -echo "generating a private key without passphrase" -openssl rsa \ - -in terraform.client.key \ - -passin "pass:$PASS" \ - -out terraform.pem - -echo "generating private key with passphrase" -openssl rsa \ - -aes256 \ - -passout "pass:$PASS" \ - -passin "pass:$PASS" \ - -in terraform.client.key \ - -out terraform-with-passphrase.pem - -for i in broker1 -do - echo $i - # Create keystores - keytool -genkey \ - -noprompt \ - -alias $i \ - -dname "CN=localhost, OU=TEST, O=CONFLUENT, L=PaloAlto, S=Ca, C=US" \ - -keystore kafka.$i.keystore.jks \ - -keyalg RSA \ - -ext SAN=dns:localhost \ - -storepass $PASS \ - -keypass $PASS - - # Create CSR, sign the key and import back into keystore - keytool \ - -keystore kafka.$i.keystore.jks \ - -alias $i \ - -certreq \ - -file $i.csr \ - -storepass $PASS \ - -noprompt \ - -keypass $PASS - - openssl x509 \ - -req \ - -CA ca.crt \ - -CAkey ca.key \ - -in $i.csr \ - -out $i-cert.crt \ - -days 9999 \ - -CAcreateserial \ - -passin pass:$PASS - - keytool \ - -keystore kafka.$i.keystore.jks \ - -alias CARoot \ - -import \ - -file ca.crt \ - -storepass $PASS \ - -noprompt \ - -keypass $PASS - - keytool -keystore kafka.$i.keystore.jks \ - -alias $i \ - -import \ - -file $i-cert.crt \ - -storepass $PASS \ - -noprompt \ - -keypass $PASS - - # Create truststore and import the CA cert. - keytool -keystore kafka.$i.truststore.jks \ - -alias CARoot \ - -import \ - -noprompt \ - -file ca.crt \ - -storepass $PASS \ - -keypass $PASS - - echo $PASS > ${i}_sslkey_creds - echo $PASS > ${i}_keystore_creds - echo $PASS > ${i}_truststore_creds +#! /usr/bin/env bash + +set -euox pipefail +IFS=$'\n\t' + +PASSWORD='test-pass' +BROKERS=('kafka1' 'kafka2' 'kafka3') +RSA_SIZE='4096' + +CN='localhost' +OU='Kitchen' +O='Krusty Krab' +L='Bikini Bottom' +ST='Bikini Atoll' +C='MH' + + +make_ca() { + local ca="$1" + local ca_key="$2" + + openssl req -x509 \ + -newkey "rsa:$RSA_SIZE" \ + -days '7300' \ + -passin "pass:$PASSWORD" \ + -passout "pass:$PASSWORD" \ + -subj "/C=$C/ST=$ST/L=$L/O=$O/OU=$OU/CN=$CN" \ + -keyout "$ca_key" \ + -out "$ca" +} + +make_keystore() { + local alias="$1" + local keystore="kafka.$alias.keystore.jks" + + keytool -noprompt -genkey \ + -keystore "$keystore" \ + -alias "$alias" \ + -validity '7300' \ + -storepass "$PASSWORD" \ + -keypass "$PASSWORD" \ + -keyalg 'RSA' \ + -keysize "$RSA_SIZE" \ + -dname "CN=$CN, OU=$OU, O=$O, L=$L, ST=$ST, C=$C" + + echo -n "$keystore" +} + +import_into_store() { + local store="$1" + local alias="$2" + local file="$3" + + keytool -noprompt -import \ + -keystore "$store" \ + -alias "$alias" \ + -file "$file" \ + -storepass "$PASSWORD" \ + -keypass "$PASSWORD" +} + +export_csr() { + local keystore="$1" + local alias="$2" + local csr="$alias.csr" + + keytool -noprompt -certreq \ + -keystore "$keystore" \ + -alias "$alias" \ + -file "$csr" \ + -storepass "$PASSWORD" \ + -keypass "$PASSWORD" + + echo -n "$csr" +} + +make_openssl_cnf() { + broker="$1" + cnf="$broker.cnf" + + echo "subjectAltName = @alt_names + +[alt_names] +DNS.1 = localhost +DNS.2 = $broker" > "$cnf" + + echo -n "$cnf" +} + +sign_csr() { + local csr="$1" + local ca="$2" + local ca_key="$3" + local broker="$4" + + local cnf=$(make_openssl_cnf "$broker") + local crt="$broker.crt" + + openssl x509 -req -CAcreateserial \ + -CA "$ca" \ + -CAkey "$ca_key" \ + -in "$csr" \ + -out "$crt" \ + -days '7300' \ + -passin "pass:$PASSWORD" \ + -extfile "$cnf" + + rm "$cnf" + echo -n "$crt" +} + + +echo "$PASSWORD" > 'password' +make_ca 'ca.crt' 'ca.key' + +import_into_store 'kafka.truststore.jks' 'CARoot' 'ca.crt' + +for broker in "${BROKERS[@]}"; do + keystore=$(make_keystore "$broker") + + csr=$(export_csr "$keystore" "$broker") + crt=$(sign_csr "$csr" 'ca.crt' 'ca.key' "$broker") + rm "$csr" + + import_into_store "$keystore" 'CARoot' 'ca.crt' + import_into_store "$keystore" "$broker" "$crt" + rm "$crt" done + +openssl genrsa -des3 -passout "pass:$PASSWORD" -out 'client.key' 4096 +openssl rsa -in 'client.key' -out 'client-no-password.key' -passin "pass:$PASSWORD" + +openssl req -new \ + -key 'client.key' \ + -out 'client.csr' \ + -subj "/C=$C/ST=$ST/L=$L/O=$O/OU=$OU/CN=$CN" \ + -passin "pass:$PASSWORD" \ + -passout "pass:$PASSWORD" + +openssl x509 -req -CAcreateserial \ + -CA 'ca.crt' \ + -CAkey 'ca.key' \ + -in 'client.csr' \ + -out 'client.pem' \ + -days '7300' \ + -passin "pass:$PASSWORD" + +rm 'client.csr' 'ca.srl' diff --git a/secrets/host.consumer.ssl.config b/secrets/host.consumer.ssl.config deleted file mode 100644 index 72c33e5d..00000000 --- a/secrets/host.consumer.ssl.config +++ /dev/null @@ -1,9 +0,0 @@ -group.id=ssl-host -ssl.truststore.location=/etc/kafka/secrets/kafka.consumer.truststore.jks -ssl.truststore.password=confluent - -ssl.keystore.location=/etc/kafka/secrets/kafka.consumer.keystore.jks -ssl.keystore.password=confluent -ssl.key.password=confluent - -security.protocol=SSL diff --git a/secrets/host.producer.ssl.config b/secrets/host.producer.ssl.config deleted file mode 100644 index 533c24f1..00000000 --- a/secrets/host.producer.ssl.config +++ /dev/null @@ -1,8 +0,0 @@ -ssl.truststore.location=/etc/kafka/secrets/kafka.producer.truststore.jks -ssl.truststore.password=confluent - -ssl.keystore.location=/etc/kafka/secrets/kafka.producer.keystore.jks -ssl.keystore.password=confluent -ssl.key.password=confluent - -security.protocol=SSL diff --git a/secrets/kafka.broker1.keystore.jks b/secrets/kafka.broker1.keystore.jks deleted file mode 100644 index b246508e09bffc21d1dc6ec2d663b2453ea2c827..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4497 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 N6N|#2VW1-N{{waGaB2Vm diff --git a/secrets/kafka.broker1.truststore.jks b/secrets/kafka.broker1.truststore.jks deleted file mode 100644 index ee88bb5e1b1027f8180c95b38ee15bdf8c83a3f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1130 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 literal 0 HcmV?d00001 diff --git a/secrets/kafka.kafka3.keystore.jks b/secrets/kafka.kafka3.keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..035a3b8ae55cf5062a11d376290bcfa9630fc721 GIT binary patch literal 7591 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 literal 0 HcmV?d00001 diff --git a/secrets/password b/secrets/password new file mode 100644 index 00000000..114b1935 --- /dev/null +++ b/secrets/password @@ -0,0 +1 @@ +test-pass diff --git a/tls-debug/main.go b/tls-debug/main.go index 104da817..e3557ca0 100644 --- a/tls-debug/main.go +++ b/tls-debug/main.go @@ -96,7 +96,7 @@ func fauxMain() error { if err != nil { return err } - tlsConf, err := kafka.NewTLSConfig(string(clientCert), string(clientKey), string(caCert), "confluent") + tlsConf, err := kafka.NewTLSConfig(string(clientCert), string(clientKey), string(caCert), "test-pass") if err != nil { return err }