Skip to content

Commit 18e56a7

Browse files
stuggiclaude
andcommitted
[lb pub endpt] Public endpoint reuse: service cert, front port, live port name
Support a MetalLB LoadBalancer public endpoint with a custom hostname, certificate and port (RHOSP 17.1 -> RHOSO 18 adoption). - Service cert: SANs come from the canonical service.GetVHostServerName set ({custom host, short, FQDN}); the custom endpointURL host is added for public and internal endpoints, a bad endpointURL falls back to the in-cluster names and is logged. A bring-your-own pod-level cert is taken from tls.api.<endpoint>.secretName (snapshotted pre-restore at every EnsureEndpointConfig call site), else one is issued. It applies to the LoadBalancer public endpoint and the internal endpoint; a Route-backed public endpoint keeps the operator-issued cert (a custom cert there goes on the Route via apiOverride.tls.secretName, which is validated only when a Route exists). Fix the cert cleanup delete target (Service cert, not Route cert). - Front port: for a TLS LoadBalancer public endpoint, inject a ports[] override with the endpointURL port, or else the director legacy port from lib-common's endpoint.LegacyPublicTLSPorts (legacyServiceName passed in by each service handler). Injection is skipped for non-TLS or routed endpoints, non-LoadBalancer Services, services without a legacy entry, multi-port Services, and while the live port is not yet named after its endpoint type ("public"), since an override carrying the old <service>-public name is rejected by the service operator's by-name port merge before the Service is patched. A watch on managed Services' port names and type wakes the control plane when the service operator renames the port. The override Spec is copied before it is mutated. - Routes: CreateRoute reads the target port name from the live Service instead of assuming it equals the object name. A user endpointURL is kept when a Route is replaced by a LoadBalancer. - Glance: return the requeue of the API that asked for it, and do not let a later endpoint's valid secret overwrite CustomTLSReady False set earlier in the same reconcile. Jira: OSPRH-39364 Jira: OSPRH-39366 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Martin Schuppert <mschuppert@redhat.com>
1 parent ea0a6b8 commit 18e56a7

25 files changed

Lines changed: 2347 additions & 115 deletions

‎api/go.mod‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ require (
1616
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20261027114429-cd022be3b3bf
1717
github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20261028101215-1d56c4e93343
1818
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20261028052944-9c675f19d0de
19-
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20261028064945-ed0ceac3c676
19+
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20261102122626-a5970f05c6a9
2020
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20261028064945-ed0ceac3c676
2121
github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20261025134505-67df8bc90b49
2222
github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20261022144157-a99fc6fde11c

‎api/go.sum‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20261028101215-1
152152
github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20261028101215-1d56c4e93343/go.mod h1:3Z7e9bX+hP32CgH6uq+cqsrJjJGRxwEFPFPSJU9PjhU=
153153
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20261028052944-9c675f19d0de h1:AUfhFaWL6U/jmzyHEG4BMm2e0AlYbRvQZja/0c3Pc7g=
154154
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20261028052944-9c675f19d0de/go.mod h1:zcEHASNtXYROUuBpF2kudpOzem2X938fhxtGZITi+Gw=
155-
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20261028064945-ed0ceac3c676 h1:TwvoiarmPsA3+hwkJJ+dDzDZPRIWibvxWIPcd+ntuKs=
156-
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20261028064945-ed0ceac3c676/go.mod h1:eqG33ZqMiKk2LI4lsIav6J6wI5XM158/N24vRwyil3o=
155+
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20261102122626-a5970f05c6a9 h1:aRFVCLwUNtudfVH6yF3CXKpiCQ+2n1Gz929l+WDiu/Q=
156+
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20261102122626-a5970f05c6a9/go.mod h1:eqG33ZqMiKk2LI4lsIav6J6wI5XM158/N24vRwyil3o=
157157
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20261023124652-eebd8803b178 h1:LHmAx+90Kuytid3fLLDMPy5FRFDJSJKOqIbOtAfVekE=
158158
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20261023124652-eebd8803b178/go.mod h1:0RZQkKhu5jCn7nUOS41YCBMuZA17r0+l8WDHEjAwOjY=
159159
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20261028064945-ed0ceac3c676 h1:W1hk8r5i2pqM4av3z6UdFg1TVIGGUCXO1M9LEEfyrsM=

‎go.mod‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ require (
2323
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20261028052944-9c675f19d0de
2424
github.com/openstack-k8s-operators/lib-common/modules/ansible v0.6.1-0.20261028064945-ed0ceac3c676
2525
github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.6.1-0.20261028064945-ed0ceac3c676
26-
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20261028064945-ed0ceac3c676
26+
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20261102122626-a5970f05c6a9
2727
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20261028064945-ed0ceac3c676
2828
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20261028064945-ed0ceac3c676
2929
github.com/openstack-k8s-operators/lib-common/modules/users v0.0.0-20261028064945-ed0ceac3c676

‎go.sum‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ github.com/openstack-k8s-operators/lib-common/modules/ansible v0.6.1-0.202610280
180180
github.com/openstack-k8s-operators/lib-common/modules/ansible v0.6.1-0.20261028064945-ed0ceac3c676/go.mod h1:TkZgZE92VUKHHNKXwuV8b7tT9toaxsZkcGffRafKCSA=
181181
github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.6.1-0.20261028064945-ed0ceac3c676 h1:fpRBzbHuic1zxhpvKkBtDhWUJmsCwdIbev+yqpK9TzI=
182182
github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.6.1-0.20261028064945-ed0ceac3c676/go.mod h1:gd7zjt11G0Ycuxr7o4LIIj3QkMxuIA6mjAe2jGqvcQg=
183-
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20261028064945-ed0ceac3c676 h1:TwvoiarmPsA3+hwkJJ+dDzDZPRIWibvxWIPcd+ntuKs=
184-
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20261028064945-ed0ceac3c676/go.mod h1:eqG33ZqMiKk2LI4lsIav6J6wI5XM158/N24vRwyil3o=
183+
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20261102122626-a5970f05c6a9 h1:aRFVCLwUNtudfVH6yF3CXKpiCQ+2n1Gz929l+WDiu/Q=
184+
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20261102122626-a5970f05c6a9/go.mod h1:eqG33ZqMiKk2LI4lsIav6J6wI5XM158/N24vRwyil3o=
185185
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20261023124652-eebd8803b178 h1:LHmAx+90Kuytid3fLLDMPy5FRFDJSJKOqIbOtAfVekE=
186186
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20261023124652-eebd8803b178/go.mod h1:0RZQkKhu5jCn7nUOS41YCBMuZA17r0+l8WDHEjAwOjY=
187187
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20261028064945-ed0ceac3c676 h1:W1hk8r5i2pqM4av3z6UdFg1TVIGGUCXO1M9LEEfyrsM=

‎internal/controller/core/openstackcontrolplane_controller.go‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func (r *OpenStackControlPlaneReconciler) GetLogger(ctx context.Context) logr.Lo
125125
// +kubebuilder:rbac:groups=redis.openstack.org,resources=redises,verbs=get;list;watch;create;update;patch;delete
126126
// +kubebuilder:rbac:groups=route.openshift.io,resources=routes,verbs=get;list;watch;create;update;patch;delete;
127127
// +kubebuilder:rbac:groups=route.openshift.io,resources=routes/custom-host,verbs=create;update;patch
128-
// +kubebuilder:rbac:groups=core,resources=services,verbs=get;list;
128+
// +kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch
129129
// +kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch;create;update;patch;delete;
130130
// +kubebuilder:rbac:groups=cert-manager.io,resources=issuers,verbs=get;list;watch;create;update;patch;delete;
131131
// +kubebuilder:rbac:groups=cert-manager.io,resources=certificates,verbs=get;list;watch;create;update;patch;delete;
@@ -228,6 +228,17 @@ func (r *OpenStackControlPlaneReconciler) Reconcile(ctx context.Context, req ctr
228228
instance.Status.ObservedGeneration = instance.Generation
229229

230230
// If we're not deleting this and the service object doesn't have our finalizer, add it.
231+
//
232+
// This must stay the only metadata write that is followed by more spec mutation, and
233+
// it returns before any is made. The reconcilers mutate instance.Spec in memory (issued
234+
// cert secret names, overrides, CA bundle names), and the deferred PatchInstance builds
235+
// its MergeFrom patch on the main resource whenever the metadata changed - that patch
236+
// would then persist those spec changes. The persisted spec is the user input the
237+
// reconcilers snapshot as the bring-your-own cert signal and the secret field indexes read;
238+
// persisted operator-issued names would be mistaken for BYO secrets (see resolveServiceCert).
239+
// The finalizer removal in reconcileDelete is safe for the same reason: no spec mutation
240+
// has happened on that path. Do not add annotation/label/finalizer writes after the spec
241+
// mutations without going through a separate patch.
231242
if instance.DeletionTimestamp.IsZero() && controllerutil.AddFinalizer(instance, helper.GetFinalizer()) || isNewInstance {
232243
return ctrl.Result{}, nil
233244
}
@@ -900,6 +911,13 @@ func (r *OpenStackControlPlaneReconciler) SetupWithManager(
900911
handler.EnqueueRequestsFromMapFunc(r.findControlPlaneForSrc),
901912
builder.WithPredicates(backup.AnnotationChangedPredicate(openstack.ServiceCertSelector)),
902913
).
914+
// the service operators rename the Service ports and set its type; the legacy
915+
// front port is injected only after that, see EnsureEndpointConfig
916+
Watches(
917+
&corev1.Service{},
918+
handler.EnqueueRequestsFromMapFunc(r.findControlPlaneForSrc),
919+
builder.WithPredicates(openstack.ServicePortOrTypeChangedPredicate()),
920+
).
903921
Complete(r)
904922
}
905923

‎internal/openstack/barbican.go‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77

88
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
9+
"github.com/openstack-k8s-operators/lib-common/modules/common/endpoint"
910
"github.com/openstack-k8s-operators/lib-common/modules/common/helper"
1011
"github.com/openstack-k8s-operators/lib-common/modules/common/service"
1112

@@ -108,6 +109,8 @@ func ReconcileBarbican(ctx context.Context, instance *corev1beta1.OpenStackContr
108109
instance.Spec.Barbican.Template.Auth.ApplicationCredentialSecret = acSecretName
109110
}
110111

112+
// snapshot pre-restore BYO service cert secret (pure user input; see resolveServiceCert)
113+
barbicanUserTLS := instance.Spec.Barbican.Template.BarbicanAPI.TLS
111114
// preserve any previously set TLS certs, set CA cert
112115
if instance.Spec.TLS.PodLevel.Enabled {
113116
instance.Spec.Barbican.Template.BarbicanAPI.TLS = barbican.Spec.BarbicanAPI.TLS
@@ -136,7 +139,8 @@ func ReconcileBarbican(ctx context.Context, instance *corev1beta1.OpenStackContr
136139
instance.Spec.Barbican.APIOverride,
137140
corev1beta1.OpenStackControlPlaneExposeBarbicanReadyCondition,
138141
false, // TODO: (mschuppert) could be removed when all integrated service support TLS
139-
instance.Spec.Barbican.Template.BarbicanAPI.TLS,
142+
barbicanUserTLS,
143+
endpoint.LegacyServiceNameBarbican,
140144
)
141145
if err != nil {
142146
return ctrlResult, err

‎internal/openstack/cinder.go‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/openstack-k8s-operators/lib-common/modules/common/annotations"
99
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
10+
"github.com/openstack-k8s-operators/lib-common/modules/common/endpoint"
1011
"github.com/openstack-k8s-operators/lib-common/modules/common/helper"
1112
"github.com/openstack-k8s-operators/lib-common/modules/common/service"
1213
"github.com/openstack-k8s-operators/lib-common/modules/common/webhook"
@@ -132,6 +133,8 @@ func ReconcileCinder(ctx context.Context, instance *corev1beta1.OpenStackControl
132133
instance.Spec.Cinder.Template.Auth.ApplicationCredentialSecret = acSecretName
133134
}
134135

136+
// snapshot pre-restore BYO service cert secret (pure user input; see resolveServiceCert)
137+
cinderUserTLS := instance.Spec.Cinder.Template.CinderAPI.TLS
135138
// preserve any previously set TLS certs,set CA cert
136139
if instance.Spec.TLS.PodLevel.Enabled {
137140
instance.Spec.Cinder.Template.CinderAPI.TLS = cinder.Spec.CinderAPI.TLS
@@ -160,7 +163,8 @@ func ReconcileCinder(ctx context.Context, instance *corev1beta1.OpenStackControl
160163
instance.Spec.Cinder.APIOverride,
161164
corev1beta1.OpenStackControlPlaneExposeCinderReadyCondition,
162165
false, // TODO (mschuppert) could be removed when all integrated service support TLS
163-
instance.Spec.Cinder.Template.CinderAPI.TLS,
166+
cinderUserTLS,
167+
endpoint.LegacyServiceNameCinder,
164168
)
165169
if err != nil {
166170
return ctrlResult, err

0 commit comments

Comments
 (0)