From f21280cd22c694b737c96760a7bf19f0fae2359b Mon Sep 17 00:00:00 2001 From: Damien Ciabrini Date: Thu, 21 Sep 2023 12:32:22 +0000 Subject: [PATCH] Helper function for TLS support in database access New function to generate the mysql flags read by oslo.db to connect to a mysql database via TLS. --- modules/common/tls/tls.go | 25 +++++++++++++ modules/common/tls/tls_test.go | 64 ++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/modules/common/tls/tls.go b/modules/common/tls/tls.go index 9ef69ec8..71d3234b 100644 --- a/modules/common/tls/tls.go +++ b/modules/common/tls/tls.go @@ -21,6 +21,7 @@ package tls import ( "context" "fmt" + "strings" "github.com/openstack-k8s-operators/lib-common/modules/common/helper" "github.com/openstack-k8s-operators/lib-common/modules/common/secret" @@ -125,3 +126,27 @@ func (t *TLS) CreateVolumes() []corev1.Volume { return volumes } + +// CreateDatabaseClientConfig - connection flags for the MySQL client +// Configures TLS connections for clients that use TLS certificates +// returns a string of mysql config statements +func (t *TLS) CreateDatabaseClientConfig() string { + conn := []string{} + // This assumes certificates are always injected in + // a common directory for all services + if t.Service.SecretName != "" { + conn = append(conn, + "ssl-cert=/etc/pki/tls/certs/tls.crt", + "ssl-key=/etc/pki/tls/private/tls.key") + } + // Client uses a CA certificate that gets merged + // into the pod's CA bundle by kolla_start + if t.Ca.CaSecretName != "" { + conn = append(conn, + "ssl-ca=/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem") + } + if len(conn) > 0 { + conn = append([]string{"ssl=1"}, conn...) + } + return strings.Join(conn, "\n") +} diff --git a/modules/common/tls/tls_test.go b/modules/common/tls/tls_test.go index 3bdcfb30..fb1650c5 100644 --- a/modules/common/tls/tls_test.go +++ b/modules/common/tls/tls_test.go @@ -17,6 +17,7 @@ limitations under the License. package tls import ( + "strings" "testing" ) @@ -107,3 +108,66 @@ func TestCreateVolumes(t *testing.T) { }) } } + +func TestGenerateTLSConnectionConfig(t *testing.T) { + tests := []struct { + name string + service *Service + ca *Ca + wantStmts []string + excludeStmts []string + }{ + { + name: "No Secrets", + service: &Service{}, + ca: &Ca{}, + wantStmts: []string{}, + excludeStmts: []string{"ssl=1", "ssl-cert=", "ssl-key=", "ssl-ca="}, + }, + { + name: "Only TLS Secret", + service: &Service{SecretName: "test-tls-secret"}, + ca: &Ca{}, + wantStmts: []string{"ssl=1", "ssl-cert=", "ssl-key="}, + excludeStmts: []string{"ssl-ca="}, + }, + { + name: "Only CA Secret", + service: &Service{}, + ca: &Ca{CaSecretName: "test-ca1"}, + wantStmts: []string{"ssl=1", "ssl-ca="}, + excludeStmts: []string{"ssl-cert=", "ssl-key="}, + }, + { + name: "TLS and CA Secrets", + service: &Service{SecretName: "test-tls-secret"}, + ca: &Ca{CaSecretName: "test-ca1"}, + wantStmts: []string{"ssl=1", "ssl-cert=", "ssl-key=", "ssl-ca="}, + excludeStmts: []string{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tlsInstance := &TLS{Service: tt.service, Ca: tt.ca} + configStr := tlsInstance.CreateDatabaseClientConfig() + var missingStmts []string + for _, stmt := range tt.wantStmts { + if !strings.Contains(configStr, stmt) { + missingStmts = append(missingStmts, stmt) + } + } + var unexpectedStmts []string + for _, stmt := range tt.excludeStmts { + if strings.Contains(configStr, stmt) { + unexpectedStmts = append(unexpectedStmts, stmt) + } + } + if len(missingStmts) != 0 || len(unexpectedStmts) != 0 { + t.Errorf("CreateDatabaseClientConfig() "+ + "missing statements: %v, unexpected statements: %v", + missingStmts, unexpectedStmts) + } + }) + } +}