Skip to content

Commit f94274c

Browse files
committed
tls fixes
1 parent 7f84ade commit f94274c

3 files changed

Lines changed: 54 additions & 86 deletions

File tree

internal/controller/assistant/openstackassistant_controller.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -324,12 +324,10 @@ func (r *OpenStackAssistantReconciler) Reconcile(ctx context.Context, req ctrl.R
324324
}
325325

326326
mcpSvcName := mcp.OpenStackClientRef + "-mcp"
327-
scheme := "http"
328327
if osclient.Spec.CaBundleSecretName != "" {
329-
scheme = "https"
330328
mcpCaBundleSecretName = osclient.Spec.CaBundleSecretName
331329
}
332-
mcpURL := fmt.Sprintf("%s://%s.%s.svc:8080/openstack/", scheme, mcpSvcName, instance.Namespace)
330+
mcpURL := fmt.Sprintf("http://%s.%s.svc:8080/openstack/", mcpSvcName, instance.Namespace)
333331
resolvedMCPServers[mcp.Name] = mcpURL
334332
Log.Info("Auto-resolved MCP server", "name", mcp.Name, "url", mcpURL, "openstackClientRef", mcp.OpenStackClientRef)
335333
} else if mcp.URL != "" {

internal/controller/client/openstackclient_controller.go

Lines changed: 26 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ import (
4141
"sigs.k8s.io/controller-runtime/pkg/reconcile"
4242

4343
keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1"
44-
"github.com/openstack-k8s-operators/lib-common/modules/certmanager"
4544
"github.com/openstack-k8s-operators/lib-common/modules/common"
46-
"github.com/openstack-k8s-operators/lib-common/modules/common/clusterdns"
45+
"github.com/openstack-k8s-operators/lib-common/modules/common/endpoint"
4746
condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
4847
"github.com/openstack-k8s-operators/lib-common/modules/common/configmap"
4948
"github.com/openstack-k8s-operators/lib-common/modules/common/env"
@@ -217,7 +216,8 @@ func (r *OpenStackClientReconciler) Reconcile(ctx context.Context, req ctrl.Requ
217216
}
218217

219218
clientLabels := map[string]string{
220-
common.AppSelector: "openstackclient",
219+
common.AppSelector: "openstackclient",
220+
common.OwnerSelector: instance.Name,
221221
}
222222

223223
configVars := make(map[string]env.Setter)
@@ -312,53 +312,28 @@ func (r *OpenStackClientReconciler) Reconcile(ctx context.Context, req ctrl.Requ
312312
instance.Status.Conditions.MarkTrue(condition.TLSInputReadyCondition, condition.InputReadyMessage)
313313

314314
// Reconcile MCP sidecar resources when enabled
315-
mcpTLSSecretName := ""
316315
if instance.Spec.MCP != nil && instance.Spec.MCP.Enabled {
317-
mcpTLSEnabled := instance.Spec.CaBundleSecretName != ""
318-
319-
if mcpTLSEnabled {
320-
issuer, err := certmanager.GetIssuerByLabels(
321-
ctx, helper,
322-
instance.Namespace,
323-
map[string]string{certmanager.RootCAIssuerInternalLabel: ""},
324-
)
325-
if err != nil {
326-
instance.Status.Conditions.Set(condition.FalseCondition(
327-
clientv1.OpenStackClientReadyCondition,
328-
condition.ErrorReason,
329-
condition.SeverityWarning,
330-
clientv1.OpenStackClientReadyErrorMessage,
331-
err.Error()))
332-
return ctrl.Result{}, err
333-
}
334-
335-
clusterDomain := clusterdns.GetDNSClusterDomain()
336-
mcpSvcName := instance.Name + "-mcp"
337-
certRequest := certmanager.CertificateRequest{
338-
IssuerName: issuer.Name,
339-
CertName: mcpSvcName + "-tls",
340-
Hostnames: []string{
341-
fmt.Sprintf("%s.%s.svc", mcpSvcName, instance.Namespace),
342-
fmt.Sprintf("%s.%s.svc.%s", mcpSvcName, instance.Namespace, clusterDomain),
343-
},
344-
Labels: map[string]string{},
345-
}
346-
certSecret, ctrlResult, err := certmanager.EnsureCert(ctx, helper, certRequest, instance)
347-
if err != nil {
348-
instance.Status.Conditions.Set(condition.FalseCondition(
349-
clientv1.OpenStackClientReadyCondition,
350-
condition.ErrorReason,
351-
condition.SeverityWarning,
352-
clientv1.OpenStackClientReadyErrorMessage,
353-
err.Error()))
354-
return ctrlResult, err
355-
} else if (ctrlResult != ctrl.Result{}) {
356-
return ctrlResult, nil
357-
}
358-
mcpTLSSecretName = certSecret.Name
359-
configVars[mcpTLSSecretName] = env.SetValue(certSecret.ResourceVersion)
316+
// Use the internal Keystone endpoint for the MCP sidecar's clouds.yaml
317+
// so it connects directly to the in-cluster service and avoids
318+
// TLS issues with the public OCP route.
319+
internalAuthURL, err := keystoneAPI.GetEndpoint(endpoint.EndpointInternal)
320+
if err != nil {
321+
instance.Status.Conditions.Set(condition.FalseCondition(
322+
clientv1.OpenStackClientReadyCondition,
323+
condition.RequestedReason,
324+
condition.SeverityInfo,
325+
"waiting for internal Keystone endpoint"))
326+
return ctrl.Result{RequeueAfter: time.Duration(5) * time.Second}, nil
360327
}
361328

329+
mcpCloudsYAML := openstackclient.MCPCloudsYAML(
330+
internalAuthURL,
331+
keystoneAPI.Spec.AdminProject,
332+
keystoneAPI.Spec.AdminUser,
333+
keystoneAPI.Spec.Region,
334+
instance.Spec.CaBundleSecretName,
335+
)
336+
362337
mcpConfigCM := &corev1.ConfigMap{
363338
ObjectMeta: metav1.ObjectMeta{
364339
Name: instance.Name + "-mcp-config",
@@ -367,14 +342,15 @@ func (r *OpenStackClientReconciler) Reconcile(ctx context.Context, req ctrl.Requ
367342
}
368343
_, err = controllerutil.CreateOrPatch(ctx, r.Client, mcpConfigCM, func() error {
369344
mcpConfigCM.Data = map[string]string{
370-
"config.yaml": openstackclient.MCPConfigYAML(instance.Spec.CaBundleSecretName, mcpTLSEnabled),
345+
"config.yaml": openstackclient.MCPConfigYAML(instance.Spec.CaBundleSecretName),
346+
"clouds.yaml": mcpCloudsYAML,
371347
}
372348
return controllerutil.SetControllerReference(instance, mcpConfigCM, r.Scheme)
373349
})
374350
if err != nil {
375351
return ctrl.Result{}, fmt.Errorf("error creating MCP config ConfigMap: %w", err)
376352
}
377-
configVars[instance.Name+"-mcp-config"] = env.SetValue(openstackclient.MCPConfigYAML(instance.Spec.CaBundleSecretName, mcpTLSEnabled))
353+
configVars[instance.Name+"-mcp-config"] = env.SetValue(openstackclient.MCPConfigYAML(instance.Spec.CaBundleSecretName) + mcpCloudsYAML)
378354

379355
}
380356

@@ -394,7 +370,6 @@ func (r *OpenStackClientReconciler) Reconcile(ctx context.Context, req ctrl.Requ
394370
mcpServiceHash, err := util.ObjectHash(map[string]interface{}{
395371
"containerImage": instance.Spec.ContainerImage,
396372
"mcpContainerImage": instance.Spec.MCP.ContainerImage,
397-
"mcpConfig": openstackclient.MCPConfigYAML(instance.Spec.CaBundleSecretName, instance.Spec.CaBundleSecretName != ""),
398373
"configVarsHash": configVarsHash,
399374
})
400375
if err != nil {
@@ -428,7 +403,7 @@ func (r *OpenStackClientReconciler) Reconcile(ctx context.Context, req ctrl.Requ
428403
},
429404
}
430405

431-
spec := openstackclient.ClientPodSpec(ctx, instance, helper, configVarsHash, mcpTLSSecretName)
406+
spec := openstackclient.ClientPodSpec(ctx, instance, helper, configVarsHash)
432407

433408
podSpecHash, err := util.ObjectHash(spec)
434409
if err != nil {

internal/openstackclient/funcs.go

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ func ClientPodSpec(
3434
instance *clientv1.OpenStackClient,
3535
helper *helper.Helper,
3636
configHash string,
37-
mcpTLSSecretName string,
3837
) corev1.PodSpec {
3938
envVars := map[string]env.Setter{}
4039
envVars["OS_CLOUD"] = env.SetValue("default")
@@ -116,9 +115,10 @@ func ClientPodSpec(
116115
if instance.Spec.MCP != nil && instance.Spec.MCP.Enabled {
117116
mcpVolumeMounts := []corev1.VolumeMount{
118117
{
119-
Name: "openstack-config",
118+
Name: "mcp-config",
120119
MountPath: "/home/cloud-admin/.config/openstack/clouds.yaml",
121120
SubPath: "clouds.yaml",
121+
ReadOnly: true,
122122
},
123123
{
124124
Name: "openstack-config-secret",
@@ -127,7 +127,8 @@ func ClientPodSpec(
127127
},
128128
{
129129
Name: "mcp-config",
130-
MountPath: "/tmp/mcp-config",
130+
MountPath: "/tmp/mcp-config/config.yaml",
131+
SubPath: "config.yaml",
131132
ReadOnly: true,
132133
},
133134
}
@@ -136,22 +137,6 @@ func ClientPodSpec(
136137
mcpVolumeMounts = append(mcpVolumeMounts, instance.Spec.CreateVolumeMounts(nil)...)
137138
}
138139

139-
if mcpTLSSecretName != "" {
140-
mcpVolumeMounts = append(mcpVolumeMounts, corev1.VolumeMount{
141-
Name: "mcp-tls",
142-
MountPath: "/etc/pki/tls/mcp",
143-
ReadOnly: true,
144-
})
145-
podSpec.Volumes = append(podSpec.Volumes, corev1.Volume{
146-
Name: "mcp-tls",
147-
VolumeSource: corev1.VolumeSource{
148-
Secret: &corev1.SecretVolumeSource{
149-
SecretName: mcpTLSSecretName,
150-
},
151-
},
152-
})
153-
}
154-
155140
podSpec.Volumes = append(podSpec.Volumes, corev1.Volume{
156141
Name: "mcp-config",
157142
VolumeSource: corev1.VolumeSource{
@@ -205,33 +190,43 @@ func ClientPodSpec(
205190
}
206191

207192
// MCPConfigYAML returns the rhos-mcps config.yaml content for the MCP sidecar
208-
func MCPConfigYAML(caBundleSecretName string, tlsEnabled bool) string {
193+
func MCPConfigYAML(caBundleSecretName string) string {
209194
caCert := ""
210195
if caBundleSecretName != "" {
211196
caCert = fmt.Sprintf("\n ca_cert: %s", tls.DownstreamTLSCABundlePath)
212197
}
213-
tlsConfig := ""
214-
allowedOriginScheme := "http"
215-
if tlsEnabled {
216-
tlsConfig = `
217-
tls:
218-
cert_file: /etc/pki/tls/mcp/tls.crt
219-
key_file: /etc/pki/tls/mcp/tls.key`
220-
allowedOriginScheme = "https"
221-
}
222198
return fmt.Sprintf(`port: 8080
223199
openstack:
224200
enabled: true
225201
allow_write: false%s
226202
openshift:
227-
enabled: false%s
203+
enabled: false
228204
mcp_transport_security:
229205
enable_dns_rebinding_protection: false
230206
allowed_hosts:
231207
- "*:*"
232208
allowed_origins:
233-
- "%s://*:*"
234-
`, caCert, tlsConfig, allowedOriginScheme)
209+
- "http://*:*"
210+
`, caCert)
211+
}
212+
213+
// MCPCloudsYAML returns a clouds.yaml using the given auth URL for the MCP sidecar.
214+
// When caBundleSecretName is set, a cacert path is included for TLS verification.
215+
func MCPCloudsYAML(authURL, projectName, userName, region, caBundleSecretName string) string {
216+
caCert := ""
217+
if caBundleSecretName != "" {
218+
caCert = fmt.Sprintf("\n cacert: %s", tls.DownstreamTLSCABundlePath)
219+
}
220+
return fmt.Sprintf(`clouds:
221+
default:
222+
auth:
223+
auth_url: %s
224+
project_name: %s
225+
username: %s
226+
user_domain_name: Default
227+
project_domain_name: Default
228+
region_name: %s%s
229+
`, authURL, projectName, userName, region, caCert)
235230
}
236231

237232
func clientPodVolumeMounts() []corev1.VolumeMount {

0 commit comments

Comments
 (0)