From 7157889136a6a9fd00018132f2eb8a2f88a412de Mon Sep 17 00:00:00 2001 From: Veronika Fisarova Date: Thu, 19 Oct 2023 15:28:16 +0200 Subject: [PATCH] Add TLS sample, functional test base for mounting volumes with TLS config, kuttl is still WIP Signed-off-by: Veronika Fisarova --- api/v1beta1/zz_generated.deepcopy.go | 6 ++ .../placement_v1beta1_placementapi.yaml | 5 ++ pkg/placement/volumes.go | 3 + tests/functional/base_test.go | 15 ++++ .../placementapi_controller_test.go | 51 +++++++------- .../common/assert_sample_deployment.yaml | 70 +++++++++++++++++++ 6 files changed, 124 insertions(+), 26 deletions(-) diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 5067acac..f1cdc317 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -24,6 +24,7 @@ package v1beta1 import ( "github.com/openstack-k8s-operators/lib-common/modules/common/condition" "github.com/openstack-k8s-operators/lib-common/modules/common/service" + "github.com/openstack-k8s-operators/lib-common/modules/common/tls" "k8s.io/apimachinery/pkg/runtime" ) @@ -184,6 +185,11 @@ func (in *PlacementAPISpec) DeepCopyInto(out *PlacementAPISpec) { copy(*out, *in) } in.Override.DeepCopyInto(&out.Override) + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(tls.TLS) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PlacementAPISpec. diff --git a/config/samples/placement_v1beta1_placementapi.yaml b/config/samples/placement_v1beta1_placementapi.yaml index c9e4d698..d914c69b 100644 --- a/config/samples/placement_v1beta1_placementapi.yaml +++ b/config/samples/placement_v1beta1_placementapi.yaml @@ -15,6 +15,11 @@ spec: preserveJobs: false replicas: 1 secret: placement-secret + # tls: + # ca: + # caSecretName: "ca-certs" + # service: + # secretName: "tls-certs" #resources: # requests: # memory: "500Mi" diff --git a/pkg/placement/volumes.go b/pkg/placement/volumes.go index 37530212..06522df6 100644 --- a/pkg/placement/volumes.go +++ b/pkg/placement/volumes.go @@ -57,6 +57,9 @@ func getVolumes(instance *placementv1.PlacementAPI) []corev1.Volume { } if instance.Spec.TLS != nil { + // fmt.Printf("Service: %+v\n", *instance.Spec.TLS.Service) // // For debug + // fmt.Printf("Ca: %+v\n", *instance.Spec.TLS.Ca) // For debug + // fmt.Println("instance.Spec.TLS is set. Adding TLS volumes...") // For debug caVolumes := instance.Spec.TLS.CreateVolumes() volumes = append(volumes, caVolumes...) } diff --git a/tests/functional/base_test.go b/tests/functional/base_test.go index bc90e4ef..03a91703 100644 --- a/tests/functional/base_test.go +++ b/tests/functional/base_test.go @@ -92,6 +92,21 @@ func GetDefaultPlacementAPISpec() map[string]interface{} { } } +func GetDefaultPlacementAPISpecWithTLS() map[string]interface{} { + return map[string]interface{}{ + "databaseInstance": "openstack", + "secret": SecretName, + "tls": map[string]interface{}{ + "ca": map[string]interface{}{ + "caSecretName": "ca-certs", + }, + "service": map[string]interface{}{ + "secretName": "tls-certs", + }, + }, + } +} + func CreatePlacementAPI(name types.NamespacedName, spec map[string]interface{}) client.Object { raw := map[string]interface{}{ diff --git a/tests/functional/placementapi_controller_test.go b/tests/functional/placementapi_controller_test.go index 97f376a3..cc5b59a6 100644 --- a/tests/functional/placementapi_controller_test.go +++ b/tests/functional/placementapi_controller_test.go @@ -684,40 +684,39 @@ var _ = Describe("PlacementAPI controller", func() { }) - When("TLS config is present", func() { - var placementAPINames Names - + Context("PlacementAPI is fully deployed with TLS", func() { BeforeEach(func() { - specWithTLS := GetDefaultPlacementAPISpec() - instance := CreatePlacementAPI(names.PlacementAPIName, specWithTLS) - placementAPINames = CreateNames(types.NamespacedName{ - Namespace: instance.GetNamespace(), - Name: instance.GetName(), - }) + DeferCleanup(th.DeleteInstance, CreatePlacementAPI(names.PlacementAPIName, GetDefaultPlacementAPISpecWithTLS())) + + DeferCleanup( + k8sClient.Delete, ctx, CreatePlacementAPISecret(namespace, SecretName)) + DeferCleanup(keystone.DeleteKeystoneAPI, keystone.CreateKeystoneAPI(namespace)) + + serviceSpec := corev1.ServiceSpec{Ports: []corev1.ServicePort{{Port: 3306}}} + DeferCleanup( + mariadb.DeleteDBService, + mariadb.CreateDBService(namespace, "openstack", serviceSpec), + ) + mariadb.SimulateMariaDBDatabaseCompleted(names.MariaDBDatabaseName) + keystone.SimulateKeystoneServiceReady(names.KeystoneServiceName) + keystone.SimulateKeystoneEndpointReady(names.KeystoneEndpointName) + th.SimulateJobSuccess(names.DBSyncJobName) + th.SimulateDeploymentReplicaReady(names.DeploymentName) + + th.ExpectCondition( + names.PlacementAPIName, + ConditionGetterFunc(PlacementConditionGetter), + condition.ReadyCondition, + corev1.ConditionTrue, + ) }) - It("should create volumes with the TLS information", func() { + It("creates TLS related volumes and volume mounts", func() { deployment := th.GetDeployment(names.DeploymentName) - Eventually(func() { - Expect(k8sClient.Get(ctx, placementAPINames.DeploymentName, deployment)).To(Succeed()) - }).Should(Succeed()) Expect(deployment.Spec.Template.Spec.Volumes).To(ContainElement(HaveField("Name", Equal("tls-certs")))) Expect(deployment.Spec.Template.Spec.Volumes).To(ContainElement(HaveField("Name", Equal("ca-certs")))) }) - - It("should create volume mounts with the TLS information", func() { - deployment := th.GetDeployment(names.DeploymentName) - Eventually(func() { - Expect(k8sClient.Get(ctx, placementAPINames.DeploymentName, deployment)).To(Succeed()) - }).Should(Succeed()) - - container := deployment.Spec.Template.Spec.Containers[0] - - Expect(container.VolumeMounts).To(ContainElement(HaveField("Name", Equal("tls-crt")))) - Expect(container.VolumeMounts).To(ContainElement(HaveField("Name", Equal("tls-key")))) - Expect(container.VolumeMounts).To(ContainElement(HaveField("Name", Equal("ca-certs")))) - }) }) }) diff --git a/tests/kuttl/common/assert_sample_deployment.yaml b/tests/kuttl/common/assert_sample_deployment.yaml index c65fbf64..abaf0389 100644 --- a/tests/kuttl/common/assert_sample_deployment.yaml +++ b/tests/kuttl/common/assert_sample_deployment.yaml @@ -237,6 +237,69 @@ metadata: kind: PlacementAPI name: placement --- +apiVersion: v1 +kind: Secret +metadata: + name: tls-certificates +type: Opaque +# Generated key/crt pair sorely for testing purposes +data: + tls.crt: | + LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURaVENDQWsyZ0F3SUJBZ0lVVnJmOGIxTElN + NktvSWU0clNLcU9vUVQ1OW44d0RRWUpLb1pJaHZjTkFRRUwKQlFBd1FqRUxNQWtHQTFVRUJoTUNX + Rmd4RlRBVEJnTlZCQWNNREVSbFptRjFiSFFnUTJsMGVURWNNQm9HQTFVRQpDZ3dUUkdWbVlYVnNk + Q0JEYjIxd1lXNTVJRXgwWkRBZUZ3MHlNekV3TVRreE16QTRNelZhRncweU5ERXdNVGd4Ck16QTRN + elZhTUVJeEN6QUpCZ05WQkFZVEFsaFlNUlV3RXdZRFZRUUhEQXhFWldaaGRXeDBJRU5wZEhreEhE + QWEKQmdOVkJBb01FMFJsWm1GMWJIUWdRMjl0Y0dGdWVTQk1kR1F3Z2dFaU1BMEdDU3FHU0liM0RR + RUJBUVVBQTRJQgpEd0F3Z2dFS0FvSUJBUUNySGJnVml3eFZjZGtnb2VCV0xhZlRIa2Fpek50SE9Z + VWhYeG9nTGVvTklaNmFyZUtvCkM4UmJNRUlxOVJNeDBuTmxkdkFVaUI2WFNjM3RGU1NBSmRJRnhQ + N3o1dXE5UVQyM3h0SFFKUzRPNnM2UUgrTEIKV25DRUFiY3BuVHA3d2hZVFlWbnZVOWFjSFh5RnBa + ZVBRcy96bGlsTzBrbkUyM0djam1XWUN1UHk3SU54NWJlKwp2VURzRmFBcTRzc0EyTGQ1SGhxNHVC + VG50eHlGUlBRMjhjZ1BlZ1dLSUlpbkNGZ1FmUnlVRGV2cVpINVJIUHk1CnBOaFl6cWVadEFqd3RX + dU5tV3NRMDJobWlvRmtERUlZQ3EyYUY5em1KTXRQNDViVUowSFlsZk1waDdpQ1pSWngKalkrakla + cFE1TzdvRnlndFNEaWliSHBpdzUwMnAwNnczbXl6QWdNQkFBR2pVekJSTUIwR0ExVWREZ1FXQkJS + RAp0a25uUTdpU3RPVEVGdGhGcCt6bGwrQlZuekFmQmdOVkhTTUVHREFXZ0JSRHRrbm5RN2lTdE9U + RUZ0aEZwK3psCmwrQlZuekFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dV + QUE0SUJBUUJaY0wyZ1lLMjAKRG1la1VJZzVsQTh3bFQwQ3hBa0J5ZFU3NGkxVHFpYWFJdTN6NmZZ + alBIY1hIYlJBR001USt3REJNd0x6WnRQWQpHdFpPWVlCZG1DUXgwaXl3R1VweGV2K0p0K2hER1Ez + c0ZkUWlCTW9uMXJYbGRKN2pkc3lwTCtVa1RRUWZ0R2dKCjNQOFNkSEZnMFJDZUdJNjZzMUZ6SkV2 + eVVNcTh4Z0R2L2c4RTBnU2VqdFNoOVNidHJ6YTVDQ0o5U2RESmlmVkwKNS9Ha1R5MW44MDRwYktG + cnpYWm5JYU9yUXdyMHNUek5UYStRd3dRRVNmRkFsZmxFSjJOWmxIZUtZNHVGRkpJZwpoSUUzMm5J + bjNCMzdJc28vY0gyejIxd09RYThha3A3ZzYyVThJWGhqUkRFQ3JxdUZub2RER2JkRkFCT2tEQmlo + CkkwUjdXUUZxYTRJVgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + + tls.key: | + LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZB + QVNDQktjd2dnU2pBZ0VBQW9JQkFRQ3JIYmdWaXd4VmNka2cKb2VCV0xhZlRIa2Fpek50SE9ZVWhY + eG9nTGVvTklaNmFyZUtvQzhSYk1FSXE5Uk14MG5ObGR2QVVpQjZYU2MzdApGU1NBSmRJRnhQN3o1 + dXE5UVQyM3h0SFFKUzRPNnM2UUgrTEJXbkNFQWJjcG5UcDd3aFlUWVZudlU5YWNIWHlGCnBaZVBR + cy96bGlsTzBrbkUyM0djam1XWUN1UHk3SU54NWJlK3ZVRHNGYUFxNHNzQTJMZDVIaHE0dUJUbnR4 + eUYKUlBRMjhjZ1BlZ1dLSUlpbkNGZ1FmUnlVRGV2cVpINVJIUHk1cE5oWXpxZVp0QWp3dFd1Tm1X + c1EwMmhtaW9GawpERUlZQ3EyYUY5em1KTXRQNDViVUowSFlsZk1waDdpQ1pSWnhqWStqSVpwUTVP + N29GeWd0U0RpaWJIcGl3NTAyCnAwNnczbXl6QWdNQkFBRUNnZ0VBQWF3ZUx2TzNjS1JXczJkeG1s + WUM1R0RRM3VseW9TMFNQSVBCN1J1VnhJQVcKSFR2aTBiS2Z2aVpvRnlSakJpTWc1cFoxZlRYaFdx + Z3BmNDRyMTZiRytUQjJMMnNMMDBLdWVEdlV0QnlRNlN0cApUbVpKWUl0aU95QUxLcmh6S0Y5NnVN + REVVTDc0ZzNrVVRQZ1QxWjRaQ3kvbUFuT3lyZDVaSzJjRzNpZ0pGMGd0Clh4MkpkWFp2bW9JRGlL + ZlRiSGtrNWhFWTByM2NmT1NucEVOVEg5a01GVlpYWkgwa0ovMXliLzlvbVBaanVXaUcKZzJkWHp3 + RFdZNXNwWWJITVlxNVVIczdKaWovVE1waWw3K0RBLzNtcGNXcXdyZGp6bDVSMXVoMGNzZXZnNWs1 + dwprRjE2aHo4dGFJWThtVkhEbEVveitPMWFJMkpyR2NkNUZuTjVQSTRrSlFLQmdRRFdGbFBDL3hH + Z1RaZzBCb2p0CmhxMEQzdDc4N08zenZYQ1R5QnZyZnRNdGtZLy9zL0Zscnl5M2llTzEwWk5Udkpi + U3l0UXp5S21nU1I5Sk1sY1oKY016dlkrTG41UzAzOFdQK0QycEhJbVZuZXFXS0hRTlZHRFJJem5J + ODk0Tnp6L2NsaSs4ak01WGVMT2NXdHU2VApROGVLU3ZKMjRZMDRmNXBncnBIVzBSczdid0tCZ1FE + TW5jRktGUXU1MG1jRjlENm5tWVRpRlBQUnVGUzZ2azJECnhwRC9kUnB2TEFJY3I4ejBqVXpFaFEv + ZTZ0byt1c3NhZDFwOGRtc3NzVmFrbTBBZ1JSR0lUSVhQc2pLell3YTUKZWxPdzdQMEp2UkgxMTkz + d1R6N2VyZ282bjdHbEMrUEN6YXp6SnVjK2VKR1l3eTlhbndDUzF6YkJRbGtyQnJRdQpYMzIyTnI1 + US9RS0JnRytaVmZLWktpUUpMdVUzM3RzSzBGZnJMd3hqcWFyY1Byb2FuMHRFWW1zbnJRdmJUbVAy + ClMvWWxJQm1nZFE4NmlOaTdPS0VCNGtLV3U0TlpoWVBTaEZIcUhOZExaU1g3WkdlRXU1NzNOQ3Nj + Q1AwVklLNlUKSG5VeGdPVjlGUDRqRTY5ejRhWFU5elBJN25HdHpISGg3RHVQMUJMYWd0WkgxajY5 + NFhJOHNOaHJBb0dBTDFHOApSWm1nWUpUYjVuQ1puTURRRGtpeUtpbnF6bFQ4TUNGWG52eEI1THZV + c1RXbXZGZUJEV0dJVGhFWjc2L2JFSC9SCm1UNzVnaGh3NVJoU09DUkE3YmhrcWFlWU9nd0luaFJB + RG9aLzdpU2ZacTlKVUMzRGFGUHZZYWRVdWNxS0haN2IKQkZCVzRnZVlCQy8vWDRHdDdFZUJEaWg5 + M29scVdkOFRmM1FoaHpFQ2dZRUFpdHR5OUhWU2Y4NjEyTkVKZFpwTApzNlBzbW9TQ3prZEljaWFp + SEk1eERYR1VydDZTV3NKWTlWL2cyaFdEVXdCYmx2NWNRcndNUTdWcFZwb2VpUGY5CjV4YjNtZ3Zl + N2owN040VlVaRlRwNDNOdmZGck84M2p0OVdybnFtRVJha0laK3V0SVVGM09YNHRVdExTSUE1VE4K + eDM3UUdYUHY4ZHB6by9ucjZvY3l5Q009Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K +--- # the actual addresses of the api endpoints are platform specific, so we can't rely on # kuttl asserts to check them. This short script gathers the addresses and checks that # the two endpoints are defined and their addresses follow the default pattern @@ -250,6 +313,13 @@ commands: assert_regex $apiEndpoints 'http:\/\/placement-internal\..+\.svc.*' assert_regex $apiEndpoints 'http:\/\/placement-public\..+\.svc.*' + # Verify if the TLS secret is mounted correctly + tlsMounted=$(oc get pod -l service=placement -o jsonpath='{.items[0].spec.volumes[?(@.name=="tls-vol")].secret.secretName}') + if [ "$tlsMounted" != "tls-certificates" ]; then + echo "TLS secret not mounted correctly." + exit 1 + fi + # when using image digests the containerImage URLs are SHA's so we verify them with a script tupleTemplate='{{ range (index .spec.template.spec.containers 1).env }}{{ .name }}{{ "#" }}{{ .value}}{{"\n"}}{{ end }}' imageTuples=$(oc get -n openstack-operators deployment placement-operator-controller-manager -o go-template="$tupleTemplate")