Skip to content

Commit aa0da32

Browse files
authored
Merge pull request #4759 from muraee/rosa-controlplane-status
✨ ROSA: Reconcile ROSAControlePlane status
2 parents e439ae2 + 3f434bb commit aa0da32

File tree

5 files changed

+61
-25
lines changed

5 files changed

+61
-25
lines changed

config/crd/bases/controlplane.cluster.x-k8s.io_rosacontrolplanes.yaml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ spec:
270270
supportRoleARN:
271271
type: string
272272
version:
273-
description: Openshift version, for example "openshift-v4.12.15".
273+
description: Openshift version, for example "openshift-v4.14.5".
274274
type: string
275275
workerRoleARN:
276276
type: string
@@ -337,6 +337,9 @@ spec:
337337
- type
338338
type: object
339339
type: array
340+
consoleURL:
341+
description: ConsoleURL is the url for the openshift console.
342+
type: string
340343
externalManagedControlPlane:
341344
default: true
342345
description: ExternalManagedControlPlane indicates to cluster-api
@@ -354,10 +357,14 @@ spec:
354357
description: Initialized denotes whether or not the control plane
355358
has the uploaded kubernetes config-map.
356359
type: boolean
360+
oidcEndpointURL:
361+
description: OIDCEndpointURL is the endpoint url for the managed OIDC
362+
porvider.
363+
type: string
357364
ready:
358365
default: false
359-
description: Ready denotes that the AWSManagedControlPlane API Server
360-
is ready to receive requests and that the VPC infra is ready.
366+
description: Ready denotes that the ROSAControlPlane API Server is
367+
ready to receive requests.
361368
type: boolean
362369
required:
363370
- ready

controllers/rosacluster_controller.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -155,25 +155,25 @@ func (r *ROSAClusterReconciler) SetupWithManager(ctx context.Context, mgr ctrl.M
155155

156156
func (r *ROSAClusterReconciler) rosaControlPlaneToManagedCluster(log *logger.Logger) handler.MapFunc {
157157
return func(ctx context.Context, o client.Object) []ctrl.Request {
158-
ROSAControlPlane, ok := o.(*rosacontrolplanev1.ROSAControlPlane)
158+
rosaControlPlane, ok := o.(*rosacontrolplanev1.ROSAControlPlane)
159159
if !ok {
160-
log.Error(errors.Errorf("expected an ROSAControlPlane, got %T instead", o), "failed to map ROSAControlPlane")
160+
log.Error(errors.Errorf("expected a ROSAControlPlane, got %T instead", o), "failed to map ROSAControlPlane")
161161
return nil
162162
}
163163

164-
log := log.WithValues("objectMapper", "awsmcpTomc", "ROSAcontrolplane", klog.KRef(ROSAControlPlane.Namespace, ROSAControlPlane.Name))
164+
log := log.WithValues("objectMapper", "rosacpTorosac", "ROSAcontrolplane", klog.KRef(rosaControlPlane.Namespace, rosaControlPlane.Name))
165165

166-
if !ROSAControlPlane.ObjectMeta.DeletionTimestamp.IsZero() {
166+
if !rosaControlPlane.ObjectMeta.DeletionTimestamp.IsZero() {
167167
log.Info("ROSAControlPlane has a deletion timestamp, skipping mapping")
168168
return nil
169169
}
170170

171-
if ROSAControlPlane.Spec.ControlPlaneEndpoint.IsZero() {
171+
if rosaControlPlane.Spec.ControlPlaneEndpoint.IsZero() {
172172
log.Debug("ROSAControlPlane has no control plane endpoint, skipping mapping")
173173
return nil
174174
}
175175

176-
cluster, err := util.GetOwnerCluster(ctx, r.Client, ROSAControlPlane.ObjectMeta)
176+
cluster, err := util.GetOwnerCluster(ctx, r.Client, rosaControlPlane.ObjectMeta)
177177
if err != nil {
178178
log.Error(err, "failed to get owning cluster")
179179
return nil
@@ -183,17 +183,17 @@ func (r *ROSAClusterReconciler) rosaControlPlaneToManagedCluster(log *logger.Log
183183
return nil
184184
}
185185

186-
managedClusterRef := cluster.Spec.InfrastructureRef
187-
if managedClusterRef == nil || managedClusterRef.Kind != "ROSACluster" {
186+
rosaClusterRef := cluster.Spec.InfrastructureRef
187+
if rosaClusterRef == nil || rosaClusterRef.Kind != "ROSACluster" {
188188
log.Info("InfrastructureRef is nil or not ROSACluster, skipping mapping")
189189
return nil
190190
}
191191

192192
return []ctrl.Request{
193193
{
194194
NamespacedName: types.NamespacedName{
195-
Name: managedClusterRef.Name,
196-
Namespace: managedClusterRef.Namespace,
195+
Name: rosaClusterRef.Name,
196+
Namespace: rosaClusterRef.Namespace,
197197
},
198198
},
199199
}

controlplane/rosa/api/v1beta2/rosacontrolplane_types.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ type RosaControlPlaneSpec struct { //nolint: maligned
4848
// The AWS Region the cluster lives in.
4949
Region *string `json:"region"`
5050

51-
// Openshift version, for example "openshift-v4.12.15".
51+
// Openshift version, for example "openshift-v4.14.5".
5252
Version *string `json:"version"`
5353

5454
// ControlPlaneEndpoint represents the endpoint used to communicate with the control plane.
@@ -463,8 +463,7 @@ type RosaControlPlaneStatus struct {
463463
// uploaded kubernetes config-map.
464464
// +optional
465465
Initialized bool `json:"initialized"`
466-
// Ready denotes that the AWSManagedControlPlane API Server is ready to
467-
// receive requests and that the VPC infra is ready.
466+
// Ready denotes that the ROSAControlPlane API Server is ready to receive requests.
468467
// +kubebuilder:default=false
469468
Ready bool `json:"ready"`
470469
// ErrorMessage indicates that there is a terminal problem reconciling the
@@ -476,6 +475,10 @@ type RosaControlPlaneStatus struct {
476475

477476
// ID is the cluster ID given by ROSA.
478477
ID *string `json:"id,omitempty"`
478+
// ConsoleURL is the url for the openshift console.
479+
ConsoleURL string `json:"consoleURL,omitempty"`
480+
// OIDCEndpointURL is the endpoint url for the managed OIDC porvider.
481+
OIDCEndpointURL string `json:"oidcEndpointURL,omitempty"`
479482
}
480483

481484
// +kubebuilder:object:root=true

controlplane/rosa/controllers/rosacontrolplane_controller.go

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
restclient "k8s.io/client-go/rest"
3434
"k8s.io/client-go/tools/clientcmd"
3535
"k8s.io/client-go/tools/clientcmd/api"
36+
"k8s.io/klog/v2"
3637
ctrl "sigs.k8s.io/controller-runtime"
3738
"sigs.k8s.io/controller-runtime/pkg/client"
3839
"sigs.k8s.io/controller-runtime/pkg/controller"
@@ -134,6 +135,8 @@ func (r *ROSAControlPlaneReconciler) Reconcile(ctx context.Context, req ctrl.Req
134135
return ctrl.Result{}, nil
135136
}
136137

138+
log = log.WithValues("cluster", klog.KObj(cluster))
139+
137140
if capiannotations.IsPaused(cluster, rosaControlPlane) {
138141
log.Info("Reconciliation is paused for this object")
139142
return ctrl.Result{}, nil
@@ -144,6 +147,7 @@ func (r *ROSAControlPlaneReconciler) Reconcile(ctx context.Context, req ctrl.Req
144147
Cluster: cluster,
145148
ControlPlane: rosaControlPlane,
146149
ControllerName: strings.ToLower(rosaControlPlaneKind),
150+
Logger: log,
147151
})
148152
if err != nil {
149153
return ctrl.Result{}, fmt.Errorf("failed to create scope: %w", err)
@@ -191,7 +195,12 @@ func (r *ROSAControlPlaneReconciler) reconcileNormal(ctx context.Context, rosaSc
191195

192196
if clusterID := cluster.ID(); clusterID != "" {
193197
rosaScope.ControlPlane.Status.ID = &clusterID
194-
if cluster.Status().State() == cmv1.ClusterStateReady {
198+
rosaScope.ControlPlane.Status.ConsoleURL = cluster.Console().URL()
199+
rosaScope.ControlPlane.Status.OIDCEndpointURL = cluster.AWS().STS().OIDCEndpointURL()
200+
rosaScope.ControlPlane.Status.Ready = false
201+
202+
switch cluster.Status().State() {
203+
case cmv1.ClusterStateReady:
195204
conditions.MarkTrue(rosaScope.ControlPlane, rosacontrolplanev1.ROSAControlPlaneReadyCondition)
196205
rosaScope.ControlPlane.Status.Ready = true
197206

@@ -204,15 +213,25 @@ func (r *ROSAControlPlaneReconciler) reconcileNormal(ctx context.Context, rosaSc
204213
if err := r.reconcileKubeconfig(ctx, rosaScope, rosaClient, cluster); err != nil {
205214
return ctrl.Result{}, fmt.Errorf("failed to reconcile kubeconfig: %w", err)
206215
}
207-
216+
return ctrl.Result{}, nil
217+
case cmv1.ClusterStateError:
218+
errorMessage := cluster.Status().ProvisionErrorMessage()
219+
rosaScope.ControlPlane.Status.FailureMessage = &errorMessage
220+
221+
conditions.MarkFalse(rosaScope.ControlPlane,
222+
rosacontrolplanev1.ROSAControlPlaneReadyCondition,
223+
string(cluster.Status().State()),
224+
clusterv1.ConditionSeverityError,
225+
cluster.Status().ProvisionErrorCode())
226+
// Cluster is in an unrecoverable state, returning nil error so that the request doesn't get requeued.
208227
return ctrl.Result{}, nil
209228
}
210229

211230
conditions.MarkFalse(rosaScope.ControlPlane,
212231
rosacontrolplanev1.ROSAControlPlaneReadyCondition,
213232
string(cluster.Status().State()),
214233
clusterv1.ConditionSeverityInfo,
215-
"")
234+
cluster.Status().Description())
216235

217236
rosaScope.Info("waiting for cluster to become ready", "state", cluster.Status().State())
218237
// Requeue so that status.ready is set to true when the cluster is fully created.
@@ -333,8 +352,7 @@ func (r *ROSAControlPlaneReconciler) reconcileNormal(ctx context.Context, rosaSc
333352

334353
newCluster, err := rosaClient.CreateCluster(clusterSpec)
335354
if err != nil {
336-
rosaScope.Info("error", "error", err)
337-
return ctrl.Result{RequeueAfter: 10 * time.Second}, nil
355+
return ctrl.Result{}, fmt.Errorf("failed to create ROSA cluster: %w", err)
338356
}
339357

340358
rosaScope.Info("cluster created", "state", newCluster.Status().State())
@@ -358,15 +376,22 @@ func (r *ROSAControlPlaneReconciler) reconcileDelete(ctx context.Context, rosaSc
358376
return ctrl.Result{}, err
359377
}
360378

361-
if cluster != nil {
379+
if cluster == nil {
380+
// cluster is fully deleted, remove finalizer.
381+
controllerutil.RemoveFinalizer(rosaScope.ControlPlane, ROSAControlPlaneFinalizer)
382+
return ctrl.Result{}, nil
383+
}
384+
385+
if cluster.Status().State() != cmv1.ClusterStateUninstalling {
362386
if err := rosaClient.DeleteCluster(cluster.ID()); err != nil {
363387
return ctrl.Result{}, err
364388
}
365389
}
366390

367-
controllerutil.RemoveFinalizer(rosaScope.ControlPlane, ROSAControlPlaneFinalizer)
368-
369-
return ctrl.Result{}, nil
391+
rosaScope.ControlPlane.Status.Ready = false
392+
rosaScope.Info("waiting for cluster to be deleted")
393+
// Requeue to remove the finalizer when the cluster is fully deleted.
394+
return ctrl.Result{RequeueAfter: time.Second * 60}, nil
370395
}
371396

372397
func (r *ROSAControlPlaneReconciler) reconcileKubeconfig(ctx context.Context, rosaScope *scope.ROSAControlPlaneScope, rosaClient *rosa.RosaClient, cluster *cmv1.Cluster) error {

exp/controllers/rosamachinepool_controller.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ func (r *ROSAMachinePoolReconciler) Reconcile(ctx context.Context, req ctrl.Requ
123123
ControlPlane: controlPlane,
124124
MachinePool: machinePool,
125125
RosaMachinePool: rosaMachinePool,
126+
Logger: log,
126127
})
127128
if err != nil {
128129
return ctrl.Result{}, errors.Wrap(err, "failed to create scope")

0 commit comments

Comments
 (0)