@@ -22,6 +22,7 @@ import (
2222 "fmt"
2323 "text/template"
2424
25+ "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
2526 common_helper "github.com/openstack-k8s-operators/lib-common/modules/common/helper"
2627 apiv1beta1 "github.com/openstack-k8s-operators/lightspeed-operator/api/v1beta1"
2728 corev1 "k8s.io/api/core/v1"
@@ -114,6 +115,38 @@ func GetMCPServerURL() string {
114115// Reconciliation
115116// ---------------------------------------------------------------------------
116117
118+ // ReconcileMCPServerTask reconciles the MCP server as a ReconcileFunc.
119+ func (r * OpenStackLightspeedReconciler ) ReconcileMCPServerTask (h * common_helper.Helper , ctx context.Context , instance * apiv1beta1.OpenStackLightspeed ) error {
120+ rhosoMCPEnabled , err := isRHOSOMCPEnabled (instance )
121+ if err != nil {
122+ return fmt .Errorf ("failed to parse dev config: %w" , err )
123+ }
124+ if rhosoMCPEnabled {
125+ openStackReady , mcpErr := r .ReconcileMCPServer (ctx , h , instance )
126+ if mcpErr != nil {
127+ instance .Status .Conditions .Set (condition .FalseCondition (
128+ apiv1beta1 .OpenStackLightspeedMCPServerReadyCondition ,
129+ condition .ErrorReason ,
130+ condition .SeverityWarning ,
131+ apiv1beta1 .DeploymentCheckFailedMessage ,
132+ mcpErr .Error (),
133+ ))
134+ return mcpErr
135+ }
136+ instance .Status .OpenStackReady = openStackReady
137+ } else {
138+ if err := r .cleanupMCPResources (ctx , h , instance ); err != nil {
139+ return err
140+ }
141+ instance .Status .OpenStackReady = false
142+ instance .Status .Conditions .MarkTrue (
143+ apiv1beta1 .OpenStackLightspeedMCPServerReadyCondition ,
144+ apiv1beta1 .OpenStackLightspeedMCPServerDisabledMessage ,
145+ )
146+ }
147+ return nil
148+ }
149+
117150// ReconcileMCPServer performs the reconciliation of the MCP server.
118151// The MCP server runs as a sidecar in the LCore pod. The OpenStack MCP tools
119152// are only configured in lightspeed-stack when OpenStackControlPlane exists and is Ready.
@@ -301,6 +334,36 @@ func extractOSCPFields(
301334 }, nil
302335}
303336
337+ // ---------------------------------------------------------------------------
338+ // Deletion
339+ // ---------------------------------------------------------------------------
340+
341+ // cleanupMCPResources removes MCP server resources when the rhoso_mcps feature
342+ // flag is disabled.
343+ func (r * OpenStackLightspeedReconciler ) cleanupMCPResources (
344+ ctx context.Context ,
345+ helper * common_helper.Helper ,
346+ instance * apiv1beta1.OpenStackLightspeed ,
347+ ) error {
348+ ns := instance .Namespace
349+
350+ resources := []client.Object {
351+ & corev1.ConfigMap {ObjectMeta : metav1.ObjectMeta {Name : MCPConfigYAMLConfigMapName , Namespace : ns }},
352+ & corev1.ConfigMap {ObjectMeta : metav1.ObjectMeta {Name : CloudsYAMLConfigMapName , Namespace : ns }},
353+ & corev1.Secret {ObjectMeta : metav1.ObjectMeta {Name : SecureYAMLSecretName , Namespace : ns }},
354+ & corev1.Secret {ObjectMeta : metav1.ObjectMeta {Name : CombinedCABundleSecretName , Namespace : ns }},
355+ }
356+
357+ for _ , obj := range resources {
358+ if err := helper .GetClient ().Delete (ctx , obj ); err != nil && ! k8s_errors .IsNotFound (err ) {
359+ return fmt .Errorf ("failed to delete %s %s: %w" , obj .GetObjectKind ().GroupVersionKind ().Kind , obj .GetName (), err )
360+ }
361+ }
362+
363+ helper .GetLogger ().Info ("RHOSO MCP resources cleaned up" )
364+ return nil
365+ }
366+
304367// copyObjectsToOpenStackLightspeedNamespace copies the required ConfigMaps and Secrets
305368// from the OpenStackControlPlane's namespace to the OpenStack Lightspeed namespace.
306369func copyObjectsToOpenStackLightspeedNamespace (
0 commit comments