@@ -22,12 +22,14 @@ import (
22
22
"encoding/json"
23
23
"fmt"
24
24
"strings"
25
+ "time"
25
26
26
27
"k8s.io/apimachinery/pkg/api/errors"
27
28
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
28
29
"k8s.io/apimachinery/pkg/runtime"
29
30
"k8s.io/apimachinery/pkg/runtime/schema"
30
31
"k8s.io/apimachinery/pkg/types"
32
+ "k8s.io/client-go/util/retry"
31
33
ctrl "sigs.k8s.io/controller-runtime"
32
34
"sigs.k8s.io/controller-runtime/pkg/client"
33
35
"sigs.k8s.io/controller-runtime/pkg/log"
@@ -116,16 +118,62 @@ func (r *ApplicationStatusReconciler) Reconcile(ctx context.Context, req ctrl.Re
116
118
return ctrl.Result {}, err
117
119
}
118
120
121
+ if cc .HealthStatus != "" {
122
+ if cc .HealthStatus == "Healthy" {
123
+ // If the health status is Healthy then simulate Progressing first then set to Healthy for ApplicationSet controller
124
+ if err := unstructured .SetNestedField (application .Object , "Progressing" , "status" , "health" , "status" ); err != nil {
125
+ log .Error (err , "unable to set healthStatus in Application status" )
126
+ return ctrl.Result {}, err
127
+ }
128
+
129
+ log .Info ("updating Application health status to Progressing" )
130
+
131
+ if err := retry .RetryOnConflict (retry .DefaultBackoff , func () error {
132
+ return r .Client .Update (ctx , application )
133
+ }); err != nil {
134
+ log .Error (err , "unable to update Application" )
135
+ return ctrl.Result {}, err
136
+ }
137
+ }
138
+
139
+ if err := unstructured .SetNestedField (newStatus , cc .HealthStatus , "health" , "status" ); err != nil {
140
+ log .Error (err , "unable to set health" )
141
+ return ctrl.Result {}, err
142
+ }
143
+ }
144
+
119
145
if cc .SyncStatus != "" {
120
146
if err := unstructured .SetNestedField (newStatus , cc .SyncStatus , "sync" , "status" ); err != nil {
121
147
log .Error (err , "unable to set sync" )
122
148
return ctrl.Result {}, err
123
149
}
124
150
}
125
151
126
- if cc .HealthStatus != "" {
127
- if err := unstructured .SetNestedField (newStatus , cc .HealthStatus , "health" , "status" ); err != nil {
128
- log .Error (err , "unable to set health" )
152
+ if cc .OperationStatePhase != "" {
153
+ if err := unstructured .SetNestedField (newStatus , cc .OperationStatePhase , "operationState" , "phase" ); err != nil {
154
+ log .Error (err , "unable to set OperationStatePhase" )
155
+ return ctrl.Result {}, err
156
+ }
157
+
158
+ if cc .OperationStateStartedAt == "" {
159
+ cc .OperationStateStartedAt = time .Now ().UTC ().Format (time .RFC3339 )
160
+ }
161
+
162
+ if err = unstructured .SetNestedField (newStatus , cc .OperationStateStartedAt , "operationState" , "startedAt" ); err != nil {
163
+ log .Error (err , "unable to set OperationStateStartedAt" )
164
+ return ctrl.Result {}, err
165
+ }
166
+
167
+ if err = unstructured .SetNestedField (newStatus , map [string ]interface {}{}, "operationState" , "operation" ); err != nil {
168
+ // Application required field, set it to empty object
169
+ log .Error (err , "unable to set operation" )
170
+ return ctrl.Result {}, err
171
+ }
172
+ }
173
+
174
+ if cc .SyncRevision != "" {
175
+ if err := unstructured .SetNestedField (newStatus , cc .SyncRevision , "sync" , "revision" ); err != nil {
176
+ log .Error (err , "unable to set SyncRevision" )
129
177
return ctrl.Result {}, err
130
178
}
131
179
}
@@ -172,8 +220,9 @@ func (r *ApplicationStatusReconciler) Reconcile(ctx context.Context, req ctrl.Re
172
220
return ctrl.Result {}, err
173
221
}
174
222
175
- err = r .Client .Update (ctx , application )
176
- if err != nil {
223
+ if err := retry .RetryOnConflict (retry .DefaultBackoff , func () error {
224
+ return r .Client .Update (ctx , application )
225
+ }); err != nil {
177
226
log .Error (err , "unable to update Application" )
178
227
return ctrl.Result {}, err
179
228
}
0 commit comments