Skip to content

Commit 4d9373d

Browse files
lmicciniclaude
andcommitted
Add TLS certificate for InstanceHA metrics endpoint
Create a cert-manager Certificate for the InstanceHA metrics service when pod-level TLS is enabled. The certificate uses the internal issuer with wildcard hostnames for the namespace, following the same pattern as EnsureOVNMetricsCert. The resulting secret (cert-instanceha-metrics) is consumed by the infra-operator InstanceHA controller. Also add the cert-instanceha-metrics secret to functional tests so the reconciler does not block waiting for cert-manager in envtest. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent cdd350d commit 4d9373d

3 files changed

Lines changed: 78 additions & 0 deletions

File tree

internal/openstack/instanceha.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ package openstack
22

33
import (
44
"context"
5+
"fmt"
56

7+
certmgrv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
8+
"github.com/openstack-k8s-operators/lib-common/modules/certmanager"
9+
"github.com/openstack-k8s-operators/lib-common/modules/common/clusterdns"
610
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
711
"github.com/openstack-k8s-operators/lib-common/modules/common/configmap"
812
"github.com/openstack-k8s-operators/lib-common/modules/common/helper"
@@ -21,6 +25,22 @@ const (
2125

2226
// ReconcileInstanceHa reconciles the instance HA configuration for the OpenStack control plane
2327
func ReconcileInstanceHa(ctx context.Context, instance *corev1beta1.OpenStackControlPlane, version *corev1beta1.OpenStackVersion, helper *helper.Helper) (ctrl.Result, error) {
28+
Log := GetLogger(ctx)
29+
30+
if instance.Spec.TLS.PodLevel.Enabled {
31+
_, err := EnsureInstanceHAMetricsCert(ctx, instance, helper)
32+
if err != nil {
33+
Log.Error(err, "Failed to ensure InstanceHA metrics certificate")
34+
instance.Status.Conditions.Set(condition.FalseCondition(
35+
corev1beta1.OpenStackControlPlaneInstanceHaCMReadyCondition,
36+
condition.ErrorReason,
37+
condition.SeverityWarning,
38+
corev1beta1.OpenStackControlPlaneInstanceHaCMReadyErrorMessage,
39+
err.Error()))
40+
return ctrl.Result{}, err
41+
}
42+
}
43+
2444
customData := map[string]string{
2545
InstanceHaImageKey: *getImg(version.Status.ContainerImages.OpenstackClientImage, &missingImageDefault),
2646
}
@@ -54,3 +74,48 @@ func ReconcileInstanceHa(ctx context.Context, instance *corev1beta1.OpenStackCon
5474

5575
return ctrl.Result{}, nil
5676
}
77+
78+
// EnsureInstanceHAMetricsCert creates a TLS certificate for InstanceHA metrics services
79+
func EnsureInstanceHAMetricsCert(ctx context.Context, instance *corev1beta1.OpenStackControlPlane, helper *helper.Helper) (string, error) {
80+
Log := GetLogger(ctx)
81+
82+
dnsSuffix := clusterdns.GetDNSClusterDomain()
83+
84+
certRequest := certmanager.CertificateRequest{
85+
IssuerName: instance.GetInternalIssuer(),
86+
CertName: "instanceha-metrics",
87+
Hostnames: []string{
88+
fmt.Sprintf("*.%s.svc", instance.Namespace),
89+
fmt.Sprintf("*.%s.svc.%s", instance.Namespace, dnsSuffix),
90+
},
91+
Ips: nil,
92+
Usages: []certmgrv1.KeyUsage{
93+
certmgrv1.UsageKeyEncipherment,
94+
certmgrv1.UsageDigitalSignature,
95+
certmgrv1.UsageServerAuth,
96+
},
97+
Labels: map[string]string{ServiceCertSelector: ""},
98+
}
99+
100+
if instance.Spec.TLS.PodLevel.Internal.Cert.Duration != nil {
101+
certRequest.Duration = &instance.Spec.TLS.PodLevel.Internal.Cert.Duration.Duration
102+
}
103+
if instance.Spec.TLS.PodLevel.Internal.Cert.RenewBefore != nil {
104+
certRequest.RenewBefore = &instance.Spec.TLS.PodLevel.Internal.Cert.RenewBefore.Duration
105+
}
106+
107+
certSecret, ctrlResult, err := certmanager.EnsureCert(
108+
ctx,
109+
helper,
110+
certRequest,
111+
nil)
112+
if err != nil {
113+
return "", err
114+
} else if (ctrlResult != ctrl.Result{}) {
115+
Log.Info("InstanceHA metrics certificate creation in progress", "certificate", certRequest.CertName)
116+
return "", fmt.Errorf("InstanceHA metrics certificate creation in progress")
117+
}
118+
119+
Log.Info("InstanceHA metrics certificate ensured", "secret", certSecret.Name, "certificate", certRequest.CertName)
120+
return certSecret.Name, nil
121+
}

test/functional/ctlplane/base_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ type Names struct {
9999
OVNDbServerNBName types.NamespacedName
100100
OVNDbServerSBName types.NamespacedName
101101
OVNMetricsCertName types.NamespacedName
102+
InstanceHAMetricsCertName types.NamespacedName
102103
NeutronOVNCertName types.NamespacedName
103104
OpenStackTopology []types.NamespacedName
104105
WatcherCertPublicRouteName types.NamespacedName
@@ -291,6 +292,10 @@ func CreateNames(openstackControlplaneName types.NamespacedName) Names {
291292
Namespace: openstackControlplaneName.Namespace,
292293
Name: "cert-ovn-metrics",
293294
},
295+
InstanceHAMetricsCertName: types.NamespacedName{
296+
Namespace: openstackControlplaneName.Namespace,
297+
Name: "cert-instanceha-metrics",
298+
},
294299
NeutronOVNCertName: types.NamespacedName{
295300
Namespace: openstackControlplaneName.Namespace,
296301
Name: "cert-neutron-ovndbs",

test/functional/ctlplane/openstackoperator_controller_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,7 @@ var _ = Describe("OpenStackOperator controller", func() {
937937
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName))
938938
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName))
939939
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNMetricsCertName))
940+
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.InstanceHAMetricsCertName))
940941
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName))
941942
DeferCleanup(
942943
th.DeleteInstance,
@@ -1259,6 +1260,7 @@ var _ = Describe("OpenStackOperator controller", func() {
12591260
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName))
12601261
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName))
12611262
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNMetricsCertName))
1263+
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.InstanceHAMetricsCertName))
12621264
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName))
12631265
spec := GetDefaultOpenStackControlPlaneSpec()
12641266
spec["tls"] = GetTLSeCustomIssuerSpec()
@@ -1388,6 +1390,7 @@ var _ = Describe("OpenStackOperator controller", func() {
13881390
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName))
13891391
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName))
13901392
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNMetricsCertName))
1393+
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.InstanceHAMetricsCertName))
13911394
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName))
13921395

13931396
DeferCleanup(k8sClient.Delete, ctx,
@@ -2083,6 +2086,7 @@ var _ = Describe("OpenStackOperator controller", func() {
20832086
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName))
20842087
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName))
20852088
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNMetricsCertName))
2089+
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.InstanceHAMetricsCertName))
20862090
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName))
20872091

20882092
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.WatcherCertPublicRouteName))
@@ -2273,6 +2277,7 @@ var _ = Describe("OpenStackOperator controller", func() {
22732277
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName))
22742278
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName))
22752279
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNMetricsCertName))
2280+
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.InstanceHAMetricsCertName))
22762281
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName))
22772282
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.WatcherCertPublicRouteName))
22782283
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.WatcherCertPublicSvcName))
@@ -2750,6 +2755,7 @@ var _ = Describe("OpenStackOperator controller", func() {
27502755
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName))
27512756
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName))
27522757
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNMetricsCertName))
2758+
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.InstanceHAMetricsCertName))
27532759
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName))
27542760

27552761
DeferCleanup(
@@ -2991,6 +2997,7 @@ var _ = Describe("OpenStackOperator controller", func() {
29912997
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName))
29922998
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName))
29932999
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNMetricsCertName))
3000+
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.InstanceHAMetricsCertName))
29943001
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName))
29953002
// create cert secret for octavia ovn client
29963003
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(types.NamespacedName{Name: "cert-octavia-ovndbs", Namespace: names.Namespace}))
@@ -4049,6 +4056,7 @@ var _ = Describe("OpenStackOperator controller nova cell deletion", func() {
40494056
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName))
40504057
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName))
40514058
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNMetricsCertName))
4059+
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.InstanceHAMetricsCertName))
40524060
DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName))
40534061

40544062
// create cert secrets for memcached instance

0 commit comments

Comments
 (0)