github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/lorry/engines/kafka/metadata_test.go (about) 1 /* 2 Copyright 2021 The Dapr Authors 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 http://www.apache.org/licenses/LICENSE-2.0 7 Unless required by applicable law or agreed to in writing, software 8 distributed under the License is distributed on an "AS IS" BASIS, 9 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 See the License for the specific language governing permissions and 11 limitations under the License. 12 */ 13 14 package kafka 15 16 import ( 17 "fmt" 18 "testing" 19 "time" 20 21 "github.com/go-logr/zapr" 22 "go.uber.org/zap" 23 24 "github.com/Shopify/sarama" 25 "github.com/stretchr/testify/require" 26 ) 27 28 var ( 29 clientCertPemMock = `-----BEGIN CERTIFICATE----- 30 Y2xpZW50Q2VydA== 31 -----END CERTIFICATE-----` 32 clientKeyMock = `-----BEGIN RSA PRIVATE KEY----- 33 Y2xpZW50S2V5 34 -----END RSA PRIVATE KEY-----` 35 caCertMock = `-----BEGIN CERTIFICATE----- 36 Y2FDZXJ0 37 -----END CERTIFICATE-----` 38 ) 39 40 func getKafka() *Kafka { 41 development, _ := zap.NewDevelopment() 42 return &Kafka{logger: zapr.NewLogger(development)} 43 } 44 45 func getBaseMetadata() map[string]string { 46 return map[string]string{"consumerGroup": "a", "clientID": "a", "brokers": "a", "disableTls": "true", "authType": mtlsAuthType, "maxMessageBytes": "2048", "initialOffset": "newest"} 47 } 48 49 func getCompleteMetadata() map[string]string { 50 return map[string]string{ 51 "consumerGroup": "a", "clientID": "a", "brokers": "a", "authType": mtlsAuthType, "maxMessageBytes": "2048", 52 skipVerify: "true", clientCert: clientCertPemMock, clientKey: clientKeyMock, caCert: caCertMock, 53 "consumeRetryInterval": "200", "initialOffset": "newest", 54 } 55 } 56 57 func TestParseMetadata(t *testing.T) { 58 k := getKafka() 59 t.Run("default kafka version", func(t *testing.T) { 60 m := getCompleteMetadata() 61 meta, err := k.getKafkaMetadata(m) 62 require.NoError(t, err) 63 require.NotNil(t, meta) 64 assertMetadata(t, meta) 65 require.Equal(t, sarama.V2_0_0_0, meta.Version) //nolint:nosnakecase 66 }) 67 68 t.Run("specific kafka version", func(t *testing.T) { 69 m := getCompleteMetadata() 70 m["version"] = "0.10.2.0" 71 meta, err := k.getKafkaMetadata(m) 72 require.NoError(t, err) 73 require.NotNil(t, meta) 74 assertMetadata(t, meta) 75 require.Equal(t, sarama.V0_10_2_0, meta.Version) //nolint:nosnakecase 76 }) 77 78 t.Run("invalid kafka version", func(t *testing.T) { 79 m := getCompleteMetadata() 80 m["version"] = "not_valid_version" 81 meta, err := k.getKafkaMetadata(m) 82 require.Error(t, err) 83 require.Nil(t, meta) 84 require.Equal(t, "kafka error: invalid kafka version", err.Error()) 85 }) 86 } 87 88 func assertMetadata(t *testing.T, meta *kafkaMetadata) { 89 require.Equal(t, "a", meta.Brokers[0]) 90 require.Equal(t, "a", meta.ConsumerGroup) 91 require.Equal(t, "a", meta.ClientID) 92 require.Equal(t, 2048, meta.MaxMessageBytes) 93 require.Equal(t, true, meta.TLSSkipVerify) 94 require.Equal(t, clientCertPemMock, meta.TLSClientCert) 95 require.Equal(t, clientKeyMock, meta.TLSClientKey) 96 require.Equal(t, caCertMock, meta.TLSCaCert) 97 require.Equal(t, 200*time.Millisecond, meta.ConsumeRetryInterval) 98 } 99 100 func TestMissingBrokers(t *testing.T) { 101 m := map[string]string{"initialOffset": "newest"} 102 k := getKafka() 103 meta, err := k.getKafkaMetadata(m) 104 require.Error(t, err) 105 require.Nil(t, meta) 106 107 require.Equal(t, "kafka error: missing 'brokers' attribute", err.Error()) 108 } 109 110 func TestMissingAuthType(t *testing.T) { 111 m := map[string]string{"brokers": "kafka.com:9092", "initialOffset": "newest"} 112 k := getKafka() 113 meta, err := k.getKafkaMetadata(m) 114 require.Error(t, err) 115 require.Nil(t, meta) 116 117 require.Equal(t, "kafka error: missing 'authType' attribute", err.Error()) 118 } 119 120 func TestMetadataUpgradeNoAuth(t *testing.T) { 121 m := map[string]string{"brokers": "akfak.com:9092", "initialOffset": "newest", "authRequired": "false"} 122 k := getKafka() 123 upgraded, err := k.upgradeMetadata(m) 124 require.Nil(t, err) 125 require.Equal(t, noAuthType, upgraded["authType"]) 126 } 127 128 func TestMetadataUpgradePasswordAuth(t *testing.T) { 129 k := getKafka() 130 m := map[string]string{"brokers": "akfak.com:9092", "initialOffset": "newest", "authRequired": "true", "saslPassword": "sassapass"} 131 upgraded, err := k.upgradeMetadata(m) 132 require.Nil(t, err) 133 require.Equal(t, passwordAuthType, upgraded["authType"]) 134 } 135 136 func TestMetadataUpgradePasswordMTLSAuth(t *testing.T) { 137 k := getKafka() 138 m := map[string]string{"brokers": "akfak.com:9092", "initialOffset": "newest", "authRequired": "true"} 139 upgraded, err := k.upgradeMetadata(m) 140 require.Nil(t, err) 141 require.Equal(t, mtlsAuthType, upgraded["authType"]) 142 } 143 144 func TestMissingSaslValues(t *testing.T) { 145 k := getKafka() 146 m := map[string]string{"brokers": "akfak.com:9092", "initialOffset": "newest", "authType": "password"} 147 meta, err := k.getKafkaMetadata(m) 148 require.Error(t, err) 149 require.Nil(t, meta) 150 151 require.Equal(t, fmt.Sprintf("kafka error: missing SASL Username for authType '%s'", passwordAuthType), err.Error()) 152 153 m["saslUsername"] = "sassafras" 154 155 meta, err = k.getKafkaMetadata(m) 156 require.Error(t, err) 157 require.Nil(t, meta) 158 159 require.Equal(t, fmt.Sprintf("kafka error: missing SASL Password for authType '%s'", passwordAuthType), err.Error()) 160 } 161 162 func TestMissingSaslValuesOnUpgrade(t *testing.T) { 163 k := getKafka() 164 m := map[string]string{"brokers": "akfak.com:9092", "initialOffset": "newest", "authRequired": "true", "saslPassword": "sassapass"} 165 upgraded, err := k.upgradeMetadata(m) 166 require.Nil(t, err) 167 meta, err := k.getKafkaMetadata(upgraded) 168 require.Error(t, err) 169 require.Nil(t, meta) 170 171 require.Equal(t, fmt.Sprintf("kafka error: missing SASL Username for authType '%s'", passwordAuthType), err.Error()) 172 } 173 174 func TestMissingOidcValues(t *testing.T) { 175 k := getKafka() 176 m := map[string]string{"brokers": "akfak.com:9092", "initialOffset": "newest", "authType": oidcAuthType} 177 meta, err := k.getKafkaMetadata(m) 178 require.Error(t, err) 179 require.Nil(t, meta) 180 require.Equal(t, fmt.Sprintf("kafka error: missing OIDC Token Endpoint for authType '%s'", oidcAuthType), err.Error()) 181 182 m["oidcTokenEndpoint"] = "https://sassa.fra/" 183 meta, err = k.getKafkaMetadata(m) 184 require.Error(t, err) 185 require.Nil(t, meta) 186 require.Equal(t, fmt.Sprintf("kafka error: missing OIDC Client ID for authType '%s'", oidcAuthType), err.Error()) 187 188 m["oidcClientID"] = "sassafras" 189 meta, err = k.getKafkaMetadata(m) 190 require.Error(t, err) 191 require.Nil(t, meta) 192 require.Equal(t, fmt.Sprintf("kafka error: missing OIDC Client Secret for authType '%s'", oidcAuthType), err.Error()) 193 194 // Check if missing scopes causes the default 'openid' to be used. 195 m["oidcClientSecret"] = "sassapass" 196 meta, err = k.getKafkaMetadata(m) 197 require.Nil(t, err) 198 require.Contains(t, meta.OidcScopes, "openid") 199 } 200 201 func TestPresentSaslValues(t *testing.T) { 202 k := getKafka() 203 m := map[string]string{ 204 "brokers": "akfak.com:9092", 205 "authType": passwordAuthType, 206 "saslUsername": "sassafras", 207 "saslPassword": "sassapass", 208 "initialOffset": "newest", 209 } 210 meta, err := k.getKafkaMetadata(m) 211 require.NoError(t, err) 212 require.NotNil(t, meta) 213 214 require.Equal(t, "sassafras", meta.SaslUsername) 215 require.Equal(t, "sassapass", meta.SaslPassword) 216 } 217 218 func TestPresentOidcValues(t *testing.T) { 219 k := getKafka() 220 m := map[string]string{ 221 "brokers": "akfak.com:9092", 222 "authType": oidcAuthType, 223 "oidcTokenEndpoint": "https://sassa.fras", 224 "oidcClientID": "sassafras", 225 "oidcClientSecret": "sassapass", 226 "oidcScopes": "akfak", 227 "initialOffset": "newest", 228 } 229 meta, err := k.getKafkaMetadata(m) 230 require.NoError(t, err) 231 require.NotNil(t, meta) 232 233 require.Equal(t, "https://sassa.fras", meta.OidcTokenEndpoint) 234 require.Equal(t, "sassafras", meta.OidcClientID) 235 require.Equal(t, "sassapass", meta.OidcClientSecret) 236 require.Contains(t, meta.OidcScopes, "akfak") 237 } 238 239 func TestInvalidAuthRequiredFlag(t *testing.T) { 240 m := map[string]string{"brokers": "akfak.com:9092", "authRequired": "maybe?????????????"} 241 k := getKafka() 242 _, err := k.upgradeMetadata(m) 243 require.Error(t, err) 244 245 require.Equal(t, "kafka error: invalid value for 'authRequired' attribute", err.Error()) 246 } 247 248 func TestInitialOffset(t *testing.T) { 249 m := map[string]string{"consumerGroup": "a", "brokers": "a", "authRequired": "false", "initialOffset": "oldest"} 250 k := getKafka() 251 upgraded, err := k.upgradeMetadata(m) 252 require.NoError(t, err) 253 meta, err := k.getKafkaMetadata(upgraded) 254 require.NoError(t, err) 255 require.Equal(t, sarama.OffsetOldest, meta.InitialOffset) 256 m["initialOffset"] = "newest" 257 meta, err = k.getKafkaMetadata(m) 258 require.NoError(t, err) 259 require.Equal(t, sarama.OffsetNewest, meta.InitialOffset) 260 } 261 262 func TestTls(t *testing.T) { 263 k := getKafka() 264 265 t.Run("disable tls", func(t *testing.T) { 266 m := getBaseMetadata() 267 meta, err := k.getKafkaMetadata(m) 268 require.NoError(t, err) 269 require.NotNil(t, meta) 270 c := &sarama.Config{} 271 err = updateTLSConfig(c, meta) 272 require.NoError(t, err) 273 require.Equal(t, false, c.Net.TLS.Enable) 274 }) 275 276 t.Run("wrong client cert format", func(t *testing.T) { 277 m := getBaseMetadata() 278 m[clientCert] = "clientCert" 279 meta, err := k.getKafkaMetadata(m) 280 require.Error(t, err) 281 require.Nil(t, meta) 282 283 require.Equal(t, "kafka error: invalid client certificate", err.Error()) 284 }) 285 286 t.Run("wrong client key format", func(t *testing.T) { 287 m := getBaseMetadata() 288 m[clientKey] = "clientKey" 289 meta, err := k.getKafkaMetadata(m) 290 require.Error(t, err) 291 require.Nil(t, meta) 292 293 require.Equal(t, "kafka error: invalid client key", err.Error()) 294 }) 295 296 t.Run("miss client key", func(t *testing.T) { 297 m := getBaseMetadata() 298 m[clientCert] = clientCertPemMock 299 meta, err := k.getKafkaMetadata(m) 300 require.Error(t, err) 301 require.Nil(t, meta) 302 303 require.Equal(t, "kafka error: clientKey or clientCert is missing", err.Error()) 304 }) 305 306 t.Run("miss client cert", func(t *testing.T) { 307 m := getBaseMetadata() 308 m[clientKey] = clientKeyMock 309 meta, err := k.getKafkaMetadata(m) 310 require.Error(t, err) 311 require.Nil(t, meta) 312 313 require.Equal(t, "kafka error: clientKey or clientCert is missing", err.Error()) 314 }) 315 316 t.Run("wrong ca cert format", func(t *testing.T) { 317 m := getBaseMetadata() 318 m[caCert] = "caCert" 319 meta, err := k.getKafkaMetadata(m) 320 require.Error(t, err) 321 require.Nil(t, meta) 322 323 require.Equal(t, "kafka error: invalid ca certificate", err.Error()) 324 }) 325 }