Skip to content

Commit 506a0a5

Browse files
committed
Generate SSL cert for ovn and neutron services running on EDPM nodes
This patch adds generations of the individual SSL certificate for each EDPM node. Those certificates are signed with the cert from the OVN SB DB and each of them have CN field set to `uuid5(hostname)` so that the same uuid can be later set as `system-id` on the EDPM node. This is mandatory to make OVN with RBAC working fine. Generated certificates are stored in secret and mounted in the ansibleee POD which provisions ovn-controller service. From there edpm-ansible role can copy it to the EDPM nodes individually. Related: #OSPRH-1921 Related: #OSPRH-1923 Related: #OSPRH-1924 Related: #OSPRH-1925 Assisted-by: claude-opus-4.6 Signed-off-by: Slawek Kaplonski <skaplons@redhat.com>
1 parent 06fee39 commit 506a0a5

13 files changed

Lines changed: 245 additions & 41 deletions

api/bases/dataplane.openstack.org_openstackdataplaneservices.yaml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,22 @@ spec:
151151
OpenstackDataPlaneServiceCert defines the property of a TLS cert issued for
152152
a dataplane service
153153
properties:
154+
commonName:
155+
description: |-
156+
CommonName overrides how the certificate Common Name is derived.
157+
When set to "system-id", the CN is a UUID5 derived from the node's
158+
ctlplane FQDN, matching the OVN chassis system-id convention.
159+
When empty, CN defaults to the short hostname.
160+
enum:
161+
- system-id
162+
type: string
154163
contents:
155164
description: |-
156165
Contents of the certificate
157-
This is a list of strings for properties that are needed in the cert
166+
This is a list of strings for properties that are needed in the cert.
167+
May be empty for client-only certificates that require no SANs.
158168
items:
159169
type: string
160-
minItems: 1
161170
type: array
162171
edpmRoleServiceName:
163172
description: |-
@@ -241,8 +250,6 @@ spec:
241250
pattern: ^[a-zA-Z0-9][a-zA-Z0-9\-_]*[a-zA-Z0-9]$
242251
type: string
243252
type: array
244-
required:
245-
- contents
246253
type: object
247254
description: TLSCerts tls certs to be generated
248255
type: object

api/core/v1beta1/openstackcontrolplane_types.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ const (
6161
OvnDbCaName = tls.DefaultCAPrefix + "ovn"
6262
// LibvirtCaName -
6363
LibvirtCaName = tls.DefaultCAPrefix + "libvirt"
64-
6564
// GlanceName - Default Glance name
6665
GlanceName = "glance"
6766
// CinderName - Default Cinder name

api/dataplane/v1beta1/openstackdataplaneservice_types.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ import (
2828
// a dataplane service
2929
type OpenstackDataPlaneServiceCert struct {
3030
// Contents of the certificate
31-
// This is a list of strings for properties that are needed in the cert
32-
// +kubebuilder:validation:Required
33-
// +kubebuilder:validation:MinItems:=1
34-
Contents []string `json:"contents"`
31+
// This is a list of strings for properties that are needed in the cert.
32+
// May be empty for client-only certificates that require no SANs.
33+
// +kubebuilder:validation:Optional
34+
Contents []string `json:"contents,omitempty"`
3535

3636
// Networks to include in SNI for the cert
3737
// +kubebuilder:validation:Optional
@@ -46,6 +46,14 @@ type OpenstackDataPlaneServiceCert struct {
4646
// +kubebuilder:validation:Optional
4747
KeyUsages []certmgrv1.KeyUsage `json:"keyUsages,omitempty" yaml:"keyUsages,omitempty"`
4848

49+
// CommonName overrides how the certificate Common Name is derived.
50+
// When set to "system-id", the CN is a UUID5 derived from the node's
51+
// ctlplane FQDN, matching the OVN chassis system-id convention.
52+
// When empty, CN defaults to the short hostname.
53+
// +kubebuilder:validation:Optional
54+
// +kubebuilder:validation:Enum=system-id
55+
CommonName string `json:"commonName,omitempty" yaml:"commonName,omitempty"`
56+
4957
// EDPMRoleServiceName is the value of the <role>_service_name variable from
5058
// the edpm-ansible role where this certificate is used. For example if the
5159
// certificate is for edpm_ovn from edpm-ansible, EDPMRoleServiceName must be

bindata/crds/crds.yaml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21434,13 +21434,22 @@ spec:
2143421434
OpenstackDataPlaneServiceCert defines the property of a TLS cert issued for
2143521435
a dataplane service
2143621436
properties:
21437+
commonName:
21438+
description: |-
21439+
CommonName overrides how the certificate Common Name is derived.
21440+
When set to "system-id", the CN is a UUID5 derived from the node's
21441+
ctlplane FQDN, matching the OVN chassis system-id convention.
21442+
When empty, CN defaults to the short hostname.
21443+
enum:
21444+
- system-id
21445+
type: string
2143721446
contents:
2143821447
description: |-
2143921448
Contents of the certificate
21440-
This is a list of strings for properties that are needed in the cert
21449+
This is a list of strings for properties that are needed in the cert.
21450+
May be empty for client-only certificates that require no SANs.
2144121451
items:
2144221452
type: string
21443-
minItems: 1
2144421453
type: array
2144521454
edpmRoleServiceName:
2144621455
description: |-
@@ -21524,8 +21533,6 @@ spec:
2152421533
pattern: ^[a-zA-Z0-9][a-zA-Z0-9\-_]*[a-zA-Z0-9]$
2152521534
type: string
2152621535
type: array
21527-
required:
21528-
- contents
2152921536
type: object
2153021537
description: TLSCerts tls certs to be generated
2153121538
type: object

config/crd/bases/dataplane.openstack.org_openstackdataplaneservices.yaml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,22 @@ spec:
151151
OpenstackDataPlaneServiceCert defines the property of a TLS cert issued for
152152
a dataplane service
153153
properties:
154+
commonName:
155+
description: |-
156+
CommonName overrides how the certificate Common Name is derived.
157+
When set to "system-id", the CN is a UUID5 derived from the node's
158+
ctlplane FQDN, matching the OVN chassis system-id convention.
159+
When empty, CN defaults to the short hostname.
160+
enum:
161+
- system-id
162+
type: string
154163
contents:
155164
description: |-
156165
Contents of the certificate
157-
This is a list of strings for properties that are needed in the cert
166+
This is a list of strings for properties that are needed in the cert.
167+
May be empty for client-only certificates that require no SANs.
158168
items:
159169
type: string
160-
minItems: 1
161170
type: array
162171
edpmRoleServiceName:
163172
description: |-
@@ -241,8 +250,6 @@ spec:
241250
pattern: ^[a-zA-Z0-9][a-zA-Z0-9\-_]*[a-zA-Z0-9]$
242251
type: string
243252
type: array
244-
required:
245-
- contents
246253
type: object
247254
description: TLSCerts tls certs to be generated
248255
type: object

config/services/dataplane_v1beta1_openstackdataplaneservice_neutron_metadata.yaml

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,11 @@ spec:
1313
name: neutron-metadata-extra-config
1414
optional: true
1515
tlsCerts:
16-
default:
17-
contents:
18-
- dnsnames
19-
- ips
20-
networks:
21-
- ctlplane
16+
rbac:
17+
commonName: system-id
2218
issuer: osp-rootca-issuer-ovn
2319
keyUsages:
2420
- digital signature
25-
- key encipherment
2621
- client auth
2722
caCerts: combined-ca-bundle
2823
containerImageFields:

config/services/dataplane_v1beta1_openstackdataplaneservice_neutron_ovn.yaml

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,11 @@ spec:
1414
name: neutron-ovn-extra-config
1515
optional: true
1616
tlsCerts:
17-
default:
18-
contents:
19-
- dnsnames
20-
- ips
21-
networks:
22-
- ctlplane
17+
rbac:
18+
commonName: system-id
2319
issuer: osp-rootca-issuer-ovn
2420
keyUsages:
2521
- digital signature
26-
- key encipherment
2722
- client auth
2823
caCerts: combined-ca-bundle
2924
containerImageFields:

config/services/dataplane_v1beta1_openstackdataplaneservice_ovn.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ spec:
2020
- key encipherment
2121
- server auth
2222
- client auth
23+
rbac:
24+
commonName: system-id
25+
issuer: osp-rootca-issuer-ovn
26+
keyUsages:
27+
- digital signature
28+
- client auth
2329
caCerts: combined-ca-bundle
2430
containerImageFields:
2531
- OvnControllerImage

config/services/dataplane_v1beta1_openstackdataplaneservice_ovn_bgp_agent.yaml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,11 @@ spec:
1111
name: ovn-bgp-agent-extra-config
1212
optional: true
1313
tlsCerts:
14-
default:
15-
contents:
16-
- dnsnames
17-
- ips
18-
networks:
19-
- ctlplane
14+
rbac:
15+
commonName: system-id
2016
issuer: osp-rootca-issuer-ovn
2117
keyUsages:
2218
- digital signature
23-
- key encipherment
24-
- server auth
2519
- client auth
2620
caCerts: combined-ca-bundle
2721
containerImageFields:

internal/dataplane/cert.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
3636

3737
certmgrv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
38+
"github.com/google/uuid"
3839
infranetworkv1 "github.com/openstack-k8s-operators/infra-operator/apis/network/v1beta1"
3940
"github.com/openstack-k8s-operators/lib-common/modules/certmanager"
4041
"github.com/openstack-k8s-operators/lib-common/modules/common/helper"
@@ -43,6 +44,17 @@ import (
4344
dataplanev1 "github.com/openstack-k8s-operators/openstack-operator/api/dataplane/v1beta1"
4445
)
4546

47+
// CommonNameSystemID is the sentinel value for OpenstackDataPlaneServiceCert.CommonName
48+
// that triggers UUID5-based CN derivation matching the OVN chassis system-id convention.
49+
const CommonNameSystemID = "system-id"
50+
51+
// computeSystemID derives a deterministic UUID5 from a name using the DNS
52+
// namespace, matching ovn-operator's ComputeSystemID() and edpm-ansible's
53+
// {{ name | to_uuid(namespace='6ba7b810-...') }}.
54+
func computeSystemID(name string) string {
55+
return uuid.NewSHA1(uuid.NameSpaceDNS, []byte(name)).String()
56+
}
57+
4658
// Generates an organized data structure that is leveraged to create the secrets.
4759
func createSecretsDataStructure(secretMaxSize int,
4860
certsData map[string][]byte,
@@ -180,7 +192,12 @@ func EnsureTLSCerts(ctx context.Context, helper *helper.Helper,
180192
nodeName)
181193
}
182194

183-
commonName := strings.Split(baseName, ".")[0]
195+
var commonName string
196+
if service.Spec.TLSCerts[certKey].CommonName == CommonNameSystemID {
197+
commonName = computeSystemID(baseName)
198+
} else {
199+
commonName = strings.Split(baseName, ".")[0]
200+
}
184201

185202
certSecret, result, err = GetTLSNodeCert(ctx, helper, instance, certName,
186203
issuer, labels, commonName, hosts, ips, service.Spec.TLSCerts[certKey].KeyUsages)

0 commit comments

Comments
 (0)