Skip to content

Commit d2b0b26

Browse files
committed
Add CA cert to bootstrap service
We want to add and trust the combined-ca-cert-bundle to the compute nodes to ensure that any third party certs are trusted. Lets use the bootstrap service to do this. This change will make sure that that bootstrap service has the combined-ca-cert bundle is mounted to /var/lib/openstack/cacerts/bootstrap. We do this by making sure that any service which has caCerts defined will mount that secret to /var/lib/openstack/cacerts/<service> Jira: OSPRH-14205
1 parent ef8ffcf commit d2b0b26

17 files changed

Lines changed: 307 additions & 41 deletions

File tree

config/services/dataplane_v1beta1_openstackdataplaneservice_bootstrap.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ metadata:
55
spec:
66
playbook: osp.edpm.bootstrap
77
edpmServiceType: bootstrap
8+
caCerts: combined-ca-bundle

pkg/dataplane/deployment.go

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,22 @@ func (d *Deployer) Deploy(services []string) (*ctrl.Result, error) {
131131
d.Status.NodeSetConditions[d.NodeSet.Name] = nsConditions
132132
return &ctrl.Result{}, err
133133
}
134+
} else if len(foundService.Spec.CACerts) > 0 {
135+
// In general, we use the install-certs service (which has AddCertMounts=true
136+
// to copy the cacerts over. This may not be early enough for some services
137+
// though. In particular, we want the bootstrap service to copy the cacerts
138+
// to the default location on the compute node.
139+
d.AeeSpec, err = d.addCACertMount(foundService)
140+
if err != nil {
141+
nsConditions.Set(condition.FalseCondition(
142+
readyCondition,
143+
condition.ErrorReason,
144+
condition.SeverityError,
145+
readyErrorMessage,
146+
err.Error()))
147+
d.Status.NodeSetConditions[d.NodeSet.Name] = nsConditions
148+
return &ctrl.Result{}, err
149+
}
134150
}
135151

136152
err = d.ConditionalDeploy(
@@ -351,38 +367,51 @@ func (d *Deployer) addCertMounts(
351367

352368
// add mount for cacert bundle, even if TLS-E is not enabled
353369
if len(service.Spec.CACerts) > 0 {
354-
log.Info("Mounting CA cert bundle for service", "service", svc)
355-
volMounts := storage.VolMounts{}
356-
cacertSecret := &corev1.Secret{}
357-
err := client.Get(d.Ctx, types.NamespacedName{Name: service.Spec.CACerts, Namespace: service.Namespace}, cacertSecret)
370+
d.AeeSpec, err = d.addCACertMount(service)
358371
if err != nil {
359372
return d.AeeSpec, err
360373
}
361-
volumeName := fmt.Sprintf("%s-%s", service.Name, service.Spec.CACerts)
362-
if len(volumeName) > apimachineryvalidation.DNS1123LabelMaxLength {
363-
hash := sha256.Sum224([]byte(volumeName))
364-
volumeName = "cacert" + hex.EncodeToString(hash[:])
365-
}
366-
cacertVolume := storage.Volume{
367-
Name: volumeName,
368-
VolumeSource: storage.VolumeSource{
369-
Secret: &corev1.SecretVolumeSource{
370-
SecretName: service.Spec.CACerts,
371-
},
372-
},
373-
}
374+
}
375+
}
374376

375-
cacertVolumeMount := corev1.VolumeMount{
376-
Name: volumeName,
377-
MountPath: path.Join(CACertPaths, service.Spec.EDPMServiceType),
378-
}
377+
return d.AeeSpec, nil
378+
}
379379

380-
volMounts.Volumes = append(volMounts.Volumes, cacertVolume)
381-
volMounts.Mounts = append(volMounts.Mounts, cacertVolumeMount)
382-
d.AeeSpec.ExtraMounts = append(d.AeeSpec.ExtraMounts, volMounts)
383-
}
380+
func (d *Deployer) addCACertMount(
381+
service dataplanev1.OpenStackDataPlaneService,
382+
) (*dataplanev1.AnsibleEESpec, error) {
383+
log := d.Helper.GetLogger()
384+
client := d.Helper.GetClient()
385+
386+
log.Info("Mounting CA cert bundle for service", "service", service)
387+
volMounts := storage.VolMounts{}
388+
cacertSecret := &corev1.Secret{}
389+
err := client.Get(d.Ctx, types.NamespacedName{Name: service.Spec.CACerts, Namespace: service.Namespace}, cacertSecret)
390+
if err != nil {
391+
return d.AeeSpec, err
392+
}
393+
volumeName := fmt.Sprintf("%s-%s", service.Name, service.Spec.CACerts)
394+
if len(volumeName) > apimachineryvalidation.DNS1123LabelMaxLength {
395+
hash := sha256.Sum224([]byte(volumeName))
396+
volumeName = "cacert" + hex.EncodeToString(hash[:])
397+
}
398+
cacertVolume := storage.Volume{
399+
Name: volumeName,
400+
VolumeSource: storage.VolumeSource{
401+
Secret: &corev1.SecretVolumeSource{
402+
SecretName: service.Spec.CACerts,
403+
},
404+
},
405+
}
406+
407+
cacertVolumeMount := corev1.VolumeMount{
408+
Name: volumeName,
409+
MountPath: path.Join(CACertPaths, service.Spec.EDPMServiceType),
384410
}
385411

412+
volMounts.Volumes = append(volMounts.Volumes, cacertVolume)
413+
volMounts.Mounts = append(volMounts.Mounts, cacertVolumeMount)
414+
d.AeeSpec.ExtraMounts = append(d.AeeSpec.ExtraMounts, volMounts)
386415
return d.AeeSpec, nil
387416
}
388417

tests/functional/dataplane/base_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,16 @@ func CreateSSHSecret(name types.NamespacedName) *corev1.Secret {
166166
)
167167
}
168168

169+
// Create CABundleSecret
170+
func CreateCABundleSecret(name types.NamespacedName) *corev1.Secret {
171+
return th.CreateSecret(
172+
types.NamespacedName{Namespace: name.Namespace, Name: name.Name},
173+
map[string][]byte{
174+
"tls-ca-bundle.pem": []byte("blah"),
175+
},
176+
)
177+
}
178+
169179
// Create OpenStackVersion
170180
func CreateOpenStackVersion(name types.NamespacedName) *unstructured.Unstructured {
171181
raw := DefaultOpenStackVersion(name)

tests/functional/dataplane/openstackdataplanedeployment_controller_test.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ var _ = Describe("Dataplane Deployment Test", func() {
2424
var dataplaneDeploymentName types.NamespacedName
2525
var dataplaneNodeSetName types.NamespacedName
2626
var dataplaneSSHSecretName types.NamespacedName
27+
var caBundleSecretName types.NamespacedName
2728
var neutronOvnMetadataSecretName types.NamespacedName
2829
var novaNeutronMetadataSecretName types.NamespacedName
2930
var novaCellComputeConfigSecretName types.NamespacedName
@@ -59,6 +60,10 @@ var _ = Describe("Dataplane Deployment Test", func() {
5960
Namespace: namespace,
6061
Name: "dataplane-ansible-ssh-private-key-secret",
6162
}
63+
caBundleSecretName = types.NamespacedName{
64+
Namespace: namespace,
65+
Name: "combined-ca-bundle",
66+
}
6267
neutronOvnMetadataSecretName = types.NamespacedName{
6368
Namespace: namespace,
6469
Name: "neutron-ovn-metadata-agent-neutron-config",
@@ -110,6 +115,7 @@ var _ = Describe("Dataplane Deployment Test", func() {
110115
When("A dataplaneDeployment is created with matching NodeSet", func() {
111116
BeforeEach(func() {
112117
CreateSSHSecret(dataplaneSSHSecretName)
118+
CreateCABundleSecret(caBundleSecretName)
113119
DeferCleanup(th.DeleteInstance, th.CreateSecret(neutronOvnMetadataSecretName, map[string][]byte{
114120
"fake_keys": []byte("blih"),
115121
}))
@@ -249,6 +255,7 @@ var _ = Describe("Dataplane Deployment Test", func() {
249255
When("A dataplaneDeployment is created with two NodeSets", func() {
250256
BeforeEach(func() {
251257
CreateSSHSecret(dataplaneSSHSecretName)
258+
CreateCABundleSecret(caBundleSecretName)
252259
DeferCleanup(th.DeleteInstance, th.CreateSecret(neutronOvnMetadataSecretName, map[string][]byte{
253260
"fake_keys": []byte("blih"),
254261
}))
@@ -430,9 +437,9 @@ var _ = Describe("Dataplane Deployment Test", func() {
430437
}
431438
ansibleEE := GetAnsibleee(ansibleeeName)
432439
if service.Spec.DeployOnAllNodeSets {
433-
g.Expect(ansibleEE.Spec.Template.Spec.Volumes).Should(HaveLen(4))
440+
g.Expect(ansibleEE.Spec.Template.Spec.Volumes).Should(HaveLen(5))
434441
} else {
435-
g.Expect(ansibleEE.Spec.Template.Spec.Volumes).Should(HaveLen(2))
442+
g.Expect(ansibleEE.Spec.Template.Spec.Volumes).Should(HaveLen(3))
436443
}
437444
ansibleEE.Status.Succeeded = 1
438445
g.Expect(th.K8sClient.Status().Update(th.Ctx, ansibleEE)).To(Succeed())
@@ -469,9 +476,9 @@ var _ = Describe("Dataplane Deployment Test", func() {
469476
}
470477
ansibleEE := GetAnsibleee(ansibleeeName)
471478
if service.Spec.DeployOnAllNodeSets {
472-
g.Expect(ansibleEE.Spec.Template.Spec.Volumes).Should(HaveLen(4))
479+
g.Expect(ansibleEE.Spec.Template.Spec.Volumes).Should(HaveLen(5))
473480
} else {
474-
g.Expect(ansibleEE.Spec.Template.Spec.Volumes).Should(HaveLen(2))
481+
g.Expect(ansibleEE.Spec.Template.Spec.Volumes).Should(HaveLen(3))
475482
}
476483
ansibleEE.Status.Succeeded = 1
477484
g.Expect(th.K8sClient.Status().Update(th.Ctx, ansibleEE)).To(Succeed())
@@ -501,6 +508,7 @@ var _ = Describe("Dataplane Deployment Test", func() {
501508
When("A dataplaneDeployment is created with a missing nodeset", func() {
502509
BeforeEach(func() {
503510
CreateSSHSecret(dataplaneSSHSecretName)
511+
CreateCABundleSecret(caBundleSecretName)
504512
DeferCleanup(th.DeleteInstance, th.CreateSecret(neutronOvnMetadataSecretName, map[string][]byte{
505513
"fake_keys": []byte("blih"),
506514
}))
@@ -638,6 +646,7 @@ var _ = Describe("Dataplane Deployment Test", func() {
638646
BeforeEach(func() {
639647
CreateDataplaneServicesWithSameServiceType(dataplaneServiceName)
640648
CreateSSHSecret(dataplaneSSHSecretName)
649+
CreateCABundleSecret(caBundleSecretName)
641650
DeferCleanup(th.DeleteInstance, th.CreateSecret(neutronOvnMetadataSecretName, map[string][]byte{
642651
"fake_keys": []byte("blih"),
643652
}))
@@ -720,6 +729,7 @@ var _ = Describe("Dataplane Deployment Test", func() {
720729
When("A dataplaneDeployment is created with two NodeSets both containing same globalservice", func() {
721730
BeforeEach(func() {
722731
CreateSSHSecret(dataplaneSSHSecretName)
732+
CreateCABundleSecret(caBundleSecretName)
723733
DeferCleanup(th.DeleteInstance, th.CreateSecret(neutronOvnMetadataSecretName, map[string][]byte{
724734
"fake_keys": []byte("blih"),
725735
}))
@@ -951,6 +961,7 @@ var _ = Describe("Dataplane Deployment Test", func() {
951961
BeforeEach(func() {
952962
CreateDataplaneServicesWithSameServiceType(dataplaneServiceName)
953963
CreateSSHSecret(dataplaneSSHSecretName)
964+
CreateCABundleSecret(caBundleSecretName)
954965
DeferCleanup(th.DeleteInstance, th.CreateSecret(neutronOvnMetadataSecretName, map[string][]byte{
955966
"fake_keys": []byte("blih"),
956967
}))
@@ -1051,6 +1062,7 @@ var _ = Describe("Dataplane Deployment Test", func() {
10511062
When("A dataplaneDeployment is created with serviceoverride containing single global service", func() {
10521063
BeforeEach(func() {
10531064
CreateSSHSecret(dataplaneSSHSecretName)
1065+
CreateCABundleSecret(caBundleSecretName)
10541066
DeferCleanup(th.DeleteInstance, th.CreateSecret(neutronOvnMetadataSecretName, map[string][]byte{
10551067
"fake_keys": []byte("blih"),
10561068
}))
@@ -1258,6 +1270,7 @@ var _ = Describe("Dataplane Deployment Test", func() {
12581270
When("A dataplaneDeployment is created with serviceoverride containing global service", func() {
12591271
BeforeEach(func() {
12601272
CreateSSHSecret(dataplaneSSHSecretName)
1273+
CreateCABundleSecret(caBundleSecretName)
12611274
DeferCleanup(th.DeleteInstance, th.CreateSecret(neutronOvnMetadataSecretName, map[string][]byte{
12621275
"fake_keys": []byte("blih"),
12631276
}))
@@ -1480,6 +1493,7 @@ var _ = Describe("Dataplane Deployment Test", func() {
14801493
When("A dataplaneDeployment is created with non-existent service in nodeset", func() {
14811494
BeforeEach(func() {
14821495
CreateSSHSecret(dataplaneSSHSecretName)
1496+
CreateCABundleSecret(caBundleSecretName)
14831497
DeferCleanup(th.DeleteInstance, th.CreateSecret(neutronOvnMetadataSecretName, map[string][]byte{
14841498
"fake_keys": []byte("blih"),
14851499
}))
@@ -1575,6 +1589,7 @@ var _ = Describe("Dataplane Deployment Test", func() {
15751589
When("A user sets TLSEnabled to true with control plane with PodLevel TLS disabled", func() {
15761590
BeforeEach(func() {
15771591
CreateSSHSecret(dataplaneSSHSecretName)
1592+
CreateCABundleSecret(caBundleSecretName)
15781593
DeferCleanup(th.DeleteInstance, th.CreateSecret(neutronOvnMetadataSecretName, map[string][]byte{
15791594
"fake_keys": []byte("blih"),
15801595
}))
@@ -1674,6 +1689,7 @@ var _ = Describe("Dataplane Deployment Test", func() {
16741689
When("A user sets TLSEnabled to true with control plane PodLevel TLS enabled", func() {
16751690
BeforeEach(func() {
16761691
CreateSSHSecret(dataplaneSSHSecretName)
1692+
CreateCABundleSecret(caBundleSecretName)
16771693
DeferCleanup(th.DeleteInstance, th.CreateSecret(neutronOvnMetadataSecretName, map[string][]byte{
16781694
"fake_keys": []byte("blih"),
16791695
}))

0 commit comments

Comments
 (0)