@@ -20,6 +20,7 @@ import (
2020 "context"
2121 "fmt"
2222 "reflect"
23+ "strings"
2324
2425 ctrl "sigs.k8s.io/controller-runtime"
2526 "sigs.k8s.io/controller-runtime/pkg/controller"
@@ -94,9 +95,28 @@ func (r *CloudStackClusterReconciliationRunner) Reconcile() (res ctrl.Result, re
9495 r .GetFailureDomains (r .FailureDomains ),
9596 r .RemoveExtraneousFailureDomains (r .FailureDomains ),
9697 r .VerifyFailureDomainCRDs ,
98+ r .GetOrCreateUnmanagedCluster ,
9799 r .SetReady )
98100}
99101
102+ // GetOrCreateUnmanagedCluster checks if an unmanaged cluster is present in Cloudstack else creates one.
103+ func (r * CloudStackClusterReconciliationRunner ) GetOrCreateUnmanagedCluster () (ctrl.Result , error ) {
104+ res , err := r .AsFailureDomainUser (& r .CSCluster .Spec .FailureDomains [0 ])()
105+ if r .ShouldReturn (res , err ) {
106+ return res , err
107+ }
108+ err = r .CSUser .GetOrCreateUnmanagedCluster (r .CAPICluster , r .ReconciliationSubject , & r .FailureDomains .Items [0 ].Spec )
109+ if err != nil {
110+ if strings .Contains (err .Error (), "Kubernetes Service plugin is disabled" ) {
111+ r .Log .Info ("Kubernetes Service plugin is disabled on CloudStack. Skipping ExternalManaged kubernetes cluster creation" )
112+ return ctrl.Result {}, nil
113+ }
114+ // Not requeueing the failure to support CloudStack v4.18 and before
115+ r .Log .Info (fmt .Sprintf ("Failed creating ExternalManaged kubernetes cluster on CloudStack. Error: %s" , err .Error ()))
116+ }
117+ return ctrl.Result {}, nil
118+ }
119+
100120// SetReady adds a finalizer and sets the cluster status to ready.
101121func (r * CloudStackClusterReconciliationRunner ) SetReady () (ctrl.Result , error ) {
102122 controllerutil .AddFinalizer (r .ReconciliationSubject , infrav1 .ClusterFinalizer )
@@ -151,10 +171,30 @@ func (r *CloudStackClusterReconciliationRunner) ReconcileDelete() (ctrl.Result,
151171 }
152172 return r .RequeueWithMessage ("Child FailureDomains still present, requeueing." )
153173 }
174+ if res , err := r .DeleteUnmanagedCluster (); r .ShouldReturn (res , err ) {
175+ return res , err
176+ }
154177 controllerutil .RemoveFinalizer (r .ReconciliationSubject , infrav1 .ClusterFinalizer )
155178 return ctrl.Result {}, nil
156179}
157180
181+ // DeleteUnmanagedCluster checks if an unmanaged cluster is present in Cloudstack and then deletes it.
182+ func (r * CloudStackClusterReconciliationRunner ) DeleteUnmanagedCluster () (ctrl.Result , error ) {
183+ // If field is present and delete fails, then requeue
184+ res , err := r .AsFailureDomainUser (& r .CSCluster .Spec .FailureDomains [0 ])()
185+ if r .ShouldReturn (res , err ) {
186+ return res , err
187+ }
188+ err = r .CSUser .DeleteUnmanagedCluster (r .ReconciliationSubject )
189+ if err != nil {
190+ if strings .Contains (err .Error (), " not found" ) {
191+ return ctrl.Result {}, nil
192+ }
193+ return r .RequeueWithMessage (fmt .Sprintf ("Deleting unmanaged kubernetes cluster on CloudStack failed. error: %s" , err .Error ()))
194+ }
195+ return ctrl.Result {}, nil
196+ }
197+
158198// Called in main, this registers the cluster reconciler to the CAPI controller manager.
159199func (reconciler * CloudStackClusterReconciler ) SetupWithManager (ctx context.Context , mgr ctrl.Manager , opts controller.Options ) error {
160200 log := ctrl .LoggerFrom (ctx )
0 commit comments