Skip to content

Commit cff89cf

Browse files
rollouts: add status conditions to remote root sync (#3849)
1 parent 1291cfb commit cff89cf

File tree

3 files changed

+67
-21
lines changed

3 files changed

+67
-21
lines changed

rollouts/api/v1alpha1/remoterootsync_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ type RemoteRootSyncStatus struct {
7070
// Conditions describes the reconciliation state of the object.
7171
Conditions []metav1.Condition `json:"conditions,omitempty"`
7272

73+
// SyncStatus describes the observed state of external sync.
7374
SyncStatus string `json:"syncStatus,omitempty"`
75+
76+
// Internal only. SyncCreated describes if the external sync has been created.
77+
SyncCreated bool `json:"syncCreated"`
7478
}
7579

7680
//+kubebuilder:object:root=true

rollouts/config/crd/bases/gitops.kpt.dev_remoterootsyncs.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,15 @@ spec:
191191
this file'
192192
format: int64
193193
type: integer
194+
syncCreated:
195+
description: Internal only. SyncCreated describes if the external
196+
sync has been created.
197+
type: boolean
194198
syncStatus:
199+
description: SyncStatus describes the observed state of external sync.
195200
type: string
201+
required:
202+
- syncCreated
196203
type: object
197204
type: object
198205
served: true

rollouts/controllers/remoterootsync_controller.go

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,12 @@ var (
6363
)
6464

6565
const (
66-
externalSyncCreatedConditionType = "ExternalSyncCreated"
66+
conditionReconciling = "Reconciling"
67+
conditionStalled = "Stalled"
68+
69+
reasonCreateSync = "CreateSync"
70+
reasonUpdateSync = "UpdateSync"
71+
reasonError = "Error"
6772
)
6873

6974
// RemoteRootSyncReconciler reconciles a RemoteRootSync object
@@ -121,10 +126,16 @@ func (r *RemoteRootSyncReconciler) Reconcile(ctx context.Context, req ctrl.Reque
121126
// The object is being deleted
122127
if controllerutil.ContainsFinalizer(&remoterootsync, myFinalizerName) {
123128
// our finalizer is present, so lets handle any external dependency
124-
if meta.IsStatusConditionTrue(remoterootsync.Status.Conditions, externalSyncCreatedConditionType) {
129+
if remoterootsync.Status.SyncCreated {
125130
// Delete the external sync resource
126131
err := r.deleteExternalResources(ctx, &remoterootsync)
127132
if err != nil && !apierrors.IsNotFound(err) {
133+
statusError := r.updateStatus(ctx, &remoterootsync, "", err)
134+
135+
if statusError != nil {
136+
logger.Error(statusError, "Failed to update status")
137+
}
138+
128139
// if fail to delete the external dependency here, return with error
129140
// so that it can be retried
130141
return ctrl.Result{}, fmt.Errorf("have problem to delete external resource: %w", err)
@@ -145,42 +156,66 @@ func (r *RemoteRootSyncReconciler) Reconcile(ctx context.Context, req ctrl.Reque
145156
return ctrl.Result{}, nil
146157
}
147158

148-
clusterRef := &remoterootsync.Spec.ClusterRef
149-
dynCl, err := r.getDynamicClientForCluster(ctx, clusterRef)
150-
if err != nil {
151-
return ctrl.Result{}, err
152-
}
159+
syncStatus, syncError := r.syncExternalSync(ctx, &remoterootsync)
153160

154-
if err := r.patchRootSync(ctx, dynCl, req.Name, &remoterootsync); err != nil {
161+
if err := r.updateStatus(ctx, &remoterootsync, syncStatus, syncError); err != nil {
162+
logger.Error(err, "Failed to update status")
155163
return ctrl.Result{}, err
156164
}
157165

158-
r.setupWatches(ctx, remoterootsync.Name, remoterootsync.Namespace, remoterootsync.Spec.ClusterRef)
166+
return ctrl.Result{}, syncError
167+
}
168+
169+
func (r *RemoteRootSyncReconciler) syncExternalSync(ctx context.Context, rrs *gitopsv1alpha1.RemoteRootSync) (string, error) {
170+
syncName := rrs.Name
171+
clusterRef := &rrs.Spec.ClusterRef
159172

160-
syncStatus, err := checkSyncStatus(ctx, dynCl, req.Name)
173+
dynCl, err := r.getDynamicClientForCluster(ctx, clusterRef)
161174
if err != nil {
162-
return ctrl.Result{}, err
175+
return "", fmt.Errorf("failed to create client: %w", err)
163176
}
164177

165-
if err := r.updateStatus(ctx, &remoterootsync, syncStatus); err != nil {
166-
logger.Error(err, "Failed to update status")
167-
return ctrl.Result{}, err
178+
if err := r.patchRootSync(ctx, dynCl, syncName, rrs); err != nil {
179+
return "", fmt.Errorf("failed to create/update sync: %w", err)
168180
}
169181

170-
return ctrl.Result{}, nil
182+
r.setupWatches(ctx, rrs.Name, rrs.Namespace, rrs.Spec.ClusterRef)
183+
184+
syncStatus, err := checkSyncStatus(ctx, dynCl, syncName)
185+
if err != nil {
186+
return "", fmt.Errorf("faild to check status: %w", err)
187+
}
188+
189+
return syncStatus, nil
171190
}
172191

173-
func (r *RemoteRootSyncReconciler) updateStatus(ctx context.Context, rrs *gitopsv1alpha1.RemoteRootSync, syncStatus string) error {
192+
func (r *RemoteRootSyncReconciler) updateStatus(ctx context.Context, rrs *gitopsv1alpha1.RemoteRootSync, syncStatus string, syncError error) error {
174193
logger := klog.FromContext(ctx)
175194

176-
// Don't update if there are no changes.
177-
178195
rrsPrior := rrs.DeepCopy()
196+
conditions := &rrs.Status.Conditions
179197

180-
rrs.Status.SyncStatus = syncStatus
181-
rrs.Status.ObservedGeneration = rrs.Generation
198+
if syncError == nil {
199+
rrs.Status.SyncStatus = syncStatus
200+
rrs.Status.SyncCreated = true
201+
202+
meta.RemoveStatusCondition(conditions, conditionReconciling)
203+
meta.RemoveStatusCondition(conditions, conditionStalled)
204+
} else {
205+
reconcileReason := reasonUpdateSync
206+
207+
rrs.Status.SyncStatus = "Unknown"
208+
209+
if !rrs.Status.SyncCreated {
210+
rrs.Status.SyncStatus = ""
211+
reconcileReason = reasonCreateSync
212+
}
182213

183-
meta.SetStatusCondition(&rrs.Status.Conditions, metav1.Condition{Type: externalSyncCreatedConditionType, Status: metav1.ConditionTrue, Reason: "SyncCreated"})
214+
meta.SetStatusCondition(conditions, metav1.Condition{Type: conditionReconciling, Status: metav1.ConditionTrue, Reason: reconcileReason})
215+
meta.SetStatusCondition(conditions, metav1.Condition{Type: conditionStalled, Status: metav1.ConditionTrue, Reason: reasonError, Message: syncError.Error()})
216+
}
217+
218+
rrs.Status.ObservedGeneration = rrs.Generation
184219

185220
if reflect.DeepEqual(rrs.Status, rrsPrior.Status) {
186221
return nil

0 commit comments

Comments
 (0)