Skip to content

Commit

Permalink
functional tests
Browse files Browse the repository at this point in the history
  • Loading branch information
olliewalsh committed Feb 22, 2024
1 parent 0490a14 commit 78a3569
Show file tree
Hide file tree
Showing 4 changed files with 450 additions and 0 deletions.
28 changes: 28 additions & 0 deletions tests/functional/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/client"

networkv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
infranetworkv1 "github.com/openstack-k8s-operators/infra-operator/apis/network/v1beta1"
condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
"github.com/openstack-k8s-operators/lib-common/modules/common/tls"
"github.com/openstack-k8s-operators/ovn-operator/api/v1beta1"
ovnv1 "github.com/openstack-k8s-operators/ovn-operator/api/v1beta1"
)
Expand All @@ -47,6 +49,19 @@ func GetDefaultOVNNorthdSpec() ovnv1.OVNNorthdSpec {
}
}

func GetTLSOVNNorthdSpec() ovnv1.OVNNorthdSpec {
spec := GetDefaultOVNNorthdSpec()
spec.TLS = tls.SimpleService{
Ca: tls.Ca{
CaBundleSecretName: CABundleSecretName,
},
GenericService: tls.GenericService{
SecretName: ptr.To(OvnDbCertSecretName),
},
}
return spec
}

func CreateOVNNorthd(namespace string, OVNNorthdName string, spec ovnv1.OVNNorthdSpec) client.Object {
name := ovn.CreateOVNNorthd(namespace, spec)
return ovn.GetOVNNorthd(name)
Expand All @@ -72,6 +87,19 @@ func GetDefaultOVNDBClusterSpec() ovnv1.OVNDBClusterSpec {
}
}

func GetTLSOVNDBClusterSpec() ovnv1.OVNDBClusterSpec {
spec := GetDefaultOVNDBClusterSpec()
spec.TLS = tls.SimpleService{
Ca: tls.Ca{
CaBundleSecretName: CABundleSecretName,
},
GenericService: tls.GenericService{
SecretName: ptr.To(OvnDbCertSecretName),
},
}
return spec
}

func CreateOVNDBCluster(namespace string, spec ovnv1.OVNDBClusterSpec) client.Object {
name := ovn.CreateOVNDBCluster(namespace, spec)
return ovn.GetOVNDBCluster(name)
Expand Down
218 changes: 218 additions & 0 deletions tests/functional/ovndbcluster_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,4 +349,222 @@ var _ = Describe("OVNDBCluster controller", func() {
)
})
})

When("OVNDBCluster is created with TLS", func() {
var OVNDBClusterName types.NamespacedName
BeforeEach(func() {
spec := GetTLSOVNDBClusterSpec()
spec.NetworkAttachment = "internalapi"
spec.DBType = v1beta1.SBDBType
instance := CreateOVNDBCluster(namespace, spec)
OVNDBClusterName = types.NamespacedName{Name: instance.GetName(), Namespace: instance.GetNamespace()}
DeferCleanup(th.DeleteInstance, instance)
internalAPINADName := types.NamespacedName{Namespace: namespace, Name: "internalapi"}
nad := th.CreateNetworkAttachmentDefinition(internalAPINADName)
DeferCleanup(th.DeleteInstance, nad)
})

It("reports that the CA secret is missing", func() {
th.ExpectConditionWithDetails(
OVNDBClusterName,
ConditionGetterFunc(OVNDBClusterConditionGetter),
condition.TLSInputReadyCondition,
corev1.ConditionFalse,
condition.ErrorReason,
fmt.Sprintf(
"TLSInput error occured in TLS sources Secret %s/combined-ca-bundle not found",
namespace,
),
)
th.ExpectCondition(
OVNDBClusterName,
ConditionGetterFunc(OVNDBClusterConditionGetter),
condition.ReadyCondition,
corev1.ConditionFalse,
)
})

It("reports that the cert secret is missing", func() {
DeferCleanup(k8sClient.Delete, ctx, th.CreateCABundleSecret(types.NamespacedName{
Name: CABundleSecretName,
Namespace: namespace,
}))
th.ExpectConditionWithDetails(
OVNDBClusterName,
ConditionGetterFunc(OVNDBClusterConditionGetter),
condition.TLSInputReadyCondition,
corev1.ConditionFalse,
condition.ErrorReason,
fmt.Sprintf(
"TLSInput error occured in TLS sources Secret %s/%s not found",
namespace, OvnDbCertSecretName,
),
)
th.ExpectCondition(
OVNDBClusterName,
ConditionGetterFunc(OVNDBClusterConditionGetter),
condition.ReadyCondition,
corev1.ConditionFalse,
)
})

It("creates a Statefulset with TLS certs attached", func() {
DeferCleanup(k8sClient.Delete, ctx, th.CreateCABundleSecret(types.NamespacedName{
Name: CABundleSecretName,
Namespace: namespace,
}))
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(types.NamespacedName{
Name: OvnDbCertSecretName,
Namespace: namespace,
}))

statefulSetName := types.NamespacedName{
Namespace: namespace,
Name: "ovsdbserver-sb",
}
th.SimulateStatefulSetReplicaReadyWithPods(statefulSetName,
map[string][]string{namespace + "/internalapi": {"10.0.0.1"}},
)

ss := th.GetStatefulSet(statefulSetName)

// check TLS volumes
th.AssertVolumeExists(CABundleSecretName, ss.Spec.Template.Spec.Volumes)
th.AssertVolumeExists("ovsdbserver-sb-tls-certs", ss.Spec.Template.Spec.Volumes)

svcC := ss.Spec.Template.Spec.Containers[0]

// check TLS volume mounts
th.AssertVolumeMountExists(CABundleSecretName, "tls-ca-bundle.pem", svcC.VolumeMounts)
th.AssertVolumeMountExists("ovsdbserver-sb-tls-certs", "tls.key", svcC.VolumeMounts)
th.AssertVolumeMountExists("ovsdbserver-sb-tls-certs", "tls.crt", svcC.VolumeMounts)
th.AssertVolumeMountExists("ovsdbserver-sb-tls-certs", "ca.crt", svcC.VolumeMounts)

// check DB url schema
Eventually(func(g Gomega) {
OVNDBCluster := GetOVNDBCluster(OVNDBClusterName)
g.Expect(OVNDBCluster.Status.DBAddress).To(HavePrefix("ssl:"))
g.Expect(OVNDBCluster.Status.InternalDBAddress).To(HavePrefix("ssl:"))
g.Expect(OVNDBCluster.Status.RaftAddress).To(HavePrefix("ssl:"))
}, timeout, interval).Should(Succeed())

// check scripts configure TLS
scriptsCM := types.NamespacedName{
Namespace: OVNDBClusterName.Namespace,
Name: fmt.Sprintf("%s-%s", OVNDBClusterName.Name, "scripts"),
}
Eventually(func() corev1.ConfigMap {
return *th.GetConfigMap(scriptsCM)
}, timeout, interval).ShouldNot(BeNil())

Expect(th.GetConfigMap(scriptsCM).Data["settings.sh"]).Should(
ContainSubstring("DB_SCHEME=\"pssl\""))
Expect(th.GetConfigMap(scriptsCM).Data["setup.sh"]).Should(And(
ContainSubstring("-db-ssl-key="),
ContainSubstring("-db-ssl-cert="),
ContainSubstring("-db-ssl-ca-cert="),
ContainSubstring("-cluster-remote-proto=ssl"),
))

th.ExpectCondition(
OVNDBClusterName,
ConditionGetterFunc(OVNDBClusterConditionGetter),
condition.ReadyCondition,
corev1.ConditionTrue,
)
})

It("reconfigures the pods when CA bundle changes", func() {
DeferCleanup(k8sClient.Delete, ctx, th.CreateCABundleSecret(types.NamespacedName{
Name: CABundleSecretName,
Namespace: namespace,
}))
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(types.NamespacedName{
Name: OvnDbCertSecretName,
Namespace: namespace,
}))

statefulSetName := types.NamespacedName{
Namespace: namespace,
Name: "ovsdbserver-sb",
}
th.SimulateStatefulSetReplicaReadyWithPods(statefulSetName,
map[string][]string{namespace + "/internalapi": {"10.0.0.1"}},
)

originalHash := GetEnvVarValue(
th.GetStatefulSet(statefulSetName).Spec.Template.Spec.Containers[0].Env,
"CONFIG_HASH",
"",
)
Expect(originalHash).NotTo(BeEmpty())

// Change the content of the CA secret
th.UpdateSecret(types.NamespacedName{
Name: CABundleSecretName,
Namespace: namespace,
},
"tls-ca-bundle.pem",
[]byte("DifferentCAData"),
)

// Assert that the pod is updated
Eventually(func(g Gomega) {
newHash := GetEnvVarValue(
th.GetStatefulSet(statefulSetName).Spec.Template.Spec.Containers[0].Env,
"CONFIG_HASH",
"",
)
g.Expect(newHash).NotTo(BeEmpty())
g.Expect(newHash).NotTo(Equal(originalHash))
}, timeout, interval).Should(Succeed())
})

It("reconfigures the pods when cert changes", func() {
DeferCleanup(k8sClient.Delete, ctx, th.CreateCABundleSecret(types.NamespacedName{
Name: CABundleSecretName,
Namespace: namespace,
}))
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(types.NamespacedName{
Name: OvnDbCertSecretName,
Namespace: namespace,
}))

statefulSetName := types.NamespacedName{
Namespace: namespace,
Name: "ovsdbserver-sb",
}
th.SimulateStatefulSetReplicaReadyWithPods(statefulSetName,
map[string][]string{namespace + "/internalapi": {"10.0.0.1"}},
)

originalHash := GetEnvVarValue(
th.GetStatefulSet(statefulSetName).Spec.Template.Spec.Containers[0].Env,
"CONFIG_HASH",
"",
)
Expect(originalHash).NotTo(BeEmpty())

// Change the content of the cert secret
th.UpdateSecret(types.NamespacedName{
Name: OvnDbCertSecretName,
Namespace: namespace,
},
"tls.crt",
[]byte("DifferentCrtData"),
)

// Assert that the pod is updated
Eventually(func(g Gomega) {
newHash := GetEnvVarValue(
th.GetStatefulSet(statefulSetName).Spec.Template.Spec.Containers[0].Env,
"CONFIG_HASH",
"",
)
g.Expect(newHash).NotTo(BeEmpty())
g.Expect(newHash).NotTo(Equal(originalHash))
}, timeout, interval).Should(Succeed())
})

})
})
Loading

0 comments on commit 78a3569

Please sign in to comment.