Skip to content

Commit 1d186a6

Browse files
Refactor controllers (#1017)
* Refactor controllers * Generated by GitHub Actions (go / generate) https://github.com/int128/argocd-commenter/actions/runs/7382542913 * Fix * Fix event reason * Fix --------- Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 36b3276 commit 1d186a6

11 files changed

Lines changed: 62 additions & 60 deletions

cmd/main.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ func main() {
114114
os.Exit(1)
115115
}
116116

117-
// comment controller
118117
if err = (&controller.ApplicationPhaseCommentReconciler{
119118
Client: mgr.GetClient(),
120119
Scheme: mgr.GetScheme(),
@@ -123,6 +122,7 @@ func main() {
123122
setupLog.Error(err, "unable to create controller", "controller", "ApplicationPhaseComment")
124123
os.Exit(1)
125124
}
125+
126126
if err = (&controller.ApplicationHealthCommentReconciler{
127127
Client: mgr.GetClient(),
128128
Scheme: mgr.GetScheme(),
@@ -132,7 +132,6 @@ func main() {
132132
os.Exit(1)
133133
}
134134

135-
// deployment controller
136135
if err = (&controller.ApplicationPhaseDeploymentReconciler{
137136
Client: mgr.GetClient(),
138137
Scheme: mgr.GetScheme(),
@@ -141,6 +140,7 @@ func main() {
141140
setupLog.Error(err, "unable to create controller", "controller", "ApplicationPhaseDeployment")
142141
os.Exit(1)
143142
}
143+
144144
if err = (&controller.ApplicationHealthDeploymentReconciler{
145145
Client: mgr.GetClient(),
146146
Scheme: mgr.GetScheme(),
@@ -149,6 +149,7 @@ func main() {
149149
setupLog.Error(err, "unable to create controller", "controller", "ApplicationHealthDeployment")
150150
os.Exit(1)
151151
}
152+
152153
if err = (&controller.ApplicationDeletionDeploymentReconciler{
153154
Client: mgr.GetClient(),
154155
Scheme: mgr.GetScheme(),

config/rbac/role.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ rules:
3737
verbs:
3838
- get
3939
- list
40-
- patch
4140
- watch
4241
- apiGroups:
4342
- ""

internal/argocd/application.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ func GetDeploymentURL(a argocdv1alpha1.Application) string {
4444
return a.Annotations["argocd-commenter.int128.github.io/deployment-url"]
4545
}
4646

47-
func GetOperationPhase(a argocdv1alpha1.Application) synccommon.OperationPhase {
47+
// GetSyncOperationPhase returns OperationState.Phase or empty string.
48+
func GetSyncOperationPhase(a argocdv1alpha1.Application) synccommon.OperationPhase {
4849
if a.Status.OperationState == nil {
4950
return ""
5051
}

internal/controller/applicationdeletiondeployment_controller.go

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,16 @@ import (
3232
"sigs.k8s.io/controller-runtime/pkg/log"
3333
)
3434

35-
// ApplicationDeletionDeploymentReconciler reconciles an Application object on deletion
35+
// ApplicationDeletionDeploymentReconciler reconciles an Application object.
36+
// It creates a deployment status when the Application is deleting.
3637
type ApplicationDeletionDeploymentReconciler struct {
3738
client.Client
3839
Scheme *runtime.Scheme
3940
Recorder record.EventRecorder
4041
Notification notification.Client
4142
}
4243

43-
//+kubebuilder:rbac:groups=argoproj.io,resources=applications,verbs=get;watch;list;patch
44+
//+kubebuilder:rbac:groups=argoproj.io,resources=applications,verbs=get;watch;list
4445
//+kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;watch;list
4546
//+kubebuilder:rbac:groups=core,resources=events,verbs=create;patch
4647

@@ -58,23 +59,18 @@ func (r *ApplicationDeletionDeploymentReconciler) Reconcile(ctx context.Context,
5859
if !isApplicationDeleting(app) {
5960
return ctrl.Result{}, nil
6061
}
61-
logger = logger.WithValues(
62-
"health", app.Status.Health.Status,
63-
"deletionTimestamp", app.DeletionTimestamp,
64-
)
65-
ctx = log.IntoContext(ctx, logger)
6662

6763
argocdURL, err := argocd.GetExternalURL(ctx, r.Client, req.Namespace)
6864
if err != nil {
6965
logger.Info("unable to determine Argo CD URL", "error", err)
7066
}
7167

7268
if err := r.Notification.CreateDeploymentStatusOnDeletion(ctx, app, argocdURL); err != nil {
73-
logger.Error(err, "unable to create a deployment status")
74-
r.Recorder.Eventf(&app, corev1.EventTypeWarning, "CreateDeploymentError",
75-
"unable to create a deployment status: %s", err)
69+
r.Recorder.Eventf(&app, corev1.EventTypeWarning, "CreateDeploymentStatusError",
70+
"unable to create a deployment status on deletion: %s", err)
7671
} else {
77-
r.Recorder.Eventf(&app, corev1.EventTypeNormal, "CreatedDeployment", "created a deployment status")
72+
r.Recorder.Eventf(&app, corev1.EventTypeNormal, "CreatedDeploymentStatus",
73+
"created a deployment status on deletion")
7874
}
7975
return ctrl.Result{}, nil
8076
}

internal/controller/applicationhealth_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import (
2626
"sigs.k8s.io/controller-runtime/pkg/log"
2727
)
2828

29-
// ApplicationHealthReconciler reconciles an Application object
29+
// ApplicationHealthReconciler reconciles an ApplicationHealth object
3030
type ApplicationHealthReconciler struct {
3131
client.Client
3232
Scheme *runtime.Scheme

internal/controller/applicationhealthcomment_controller.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,20 @@ import (
3636
"sigs.k8s.io/controller-runtime/pkg/log"
3737
)
3838

39-
// ApplicationHealthCommentReconciler reconciles a change of Application object
39+
// ApplicationHealthCommentReconciler reconciles a change of Application object.
40+
// It creates a comment when the health status is changed.
4041
type ApplicationHealthCommentReconciler struct {
4142
client.Client
4243
Scheme *runtime.Scheme
4344
Recorder record.EventRecorder
4445
Notification notification.Client
4546
}
4647

47-
//+kubebuilder:rbac:groups=argoproj.io,resources=applications,verbs=get;watch;list;patch
48+
//+kubebuilder:rbac:groups=argoproj.io,resources=applications,verbs=get;watch;list
4849
//+kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;watch;list
50+
//+kubebuilder:rbac:groups=core,resources=events,verbs=create;patch
4951
//+kubebuilder:rbac:groups=argocdcommenter.int128.github.io,resources=applicationhealths,verbs=get;list;watch;create;update;patch
5052
//+kubebuilder:rbac:groups=argocdcommenter.int128.github.io,resources=applicationhealths/status,verbs=get;update;patch
51-
//+kubebuilder:rbac:groups=core,resources=events,verbs=create;patch
5253

5354
func (r *ApplicationHealthCommentReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
5455
logger := log.FromContext(ctx)
@@ -98,11 +99,11 @@ func (r *ApplicationHealthCommentReconciler) Reconcile(ctx context.Context, req
9899
}
99100

100101
if err := r.Notification.CreateCommentsOnHealthChanged(ctx, app, argocdURL); err != nil {
101-
logger.Error(err, "unable to create comments")
102102
r.Recorder.Eventf(&app, corev1.EventTypeWarning, "CreateCommentError",
103-
"unable to create a comment by %s: %s", app.Status.Health.Status, err)
103+
"unable to create a comment on health status %s: %s", app.Status.Health.Status, err)
104104
} else {
105-
r.Recorder.Eventf(&app, corev1.EventTypeNormal, "CreatedComment", "created a comment by %s", app.Status.Health.Status)
105+
r.Recorder.Eventf(&app, corev1.EventTypeNormal, "CreatedComment",
106+
"created a comment on health status %s", app.Status.Health.Status)
106107
}
107108

108109
if app.Status.Health.Status != health.HealthStatusHealthy {
@@ -111,11 +112,10 @@ func (r *ApplicationHealthCommentReconciler) Reconcile(ctx context.Context, req
111112
patch := client.MergeFrom(appHealth.DeepCopy())
112113
appHealth.Status.LastHealthyRevision = currentRevision
113114
if err := r.Client.Status().Patch(ctx, &appHealth, patch); err != nil {
114-
logger.Error(err, "unable to patch lastHealthyRevision of ApplicationHealth")
115+
logger.Error(err, "unable to patch lastHealthyRevision")
115116
return ctrl.Result{}, client.IgnoreNotFound(err)
116117
}
117-
logger.Info("patched lastHealthyRevision of ApplicationHealth")
118-
r.Recorder.Eventf(&appHealth, corev1.EventTypeNormal, "UpdateLastHealthyRevision",
118+
r.Recorder.Eventf(&appHealth, corev1.EventTypeNormal, "UpdatedLastHealthyRevision",
119119
"patched lastHealthyRevision to %s", currentRevision)
120120
return ctrl.Result{}, nil
121121
}

internal/controller/applicationhealthdeployment_controller.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,20 @@ var (
4545
requeueTimeoutWhenDeploymentNotFound = 10 * time.Minute
4646
)
4747

48-
// ApplicationHealthDeploymentReconciler reconciles an Application object
48+
// ApplicationHealthDeploymentReconciler reconciles an Application object.
49+
// It creates a deployment status when the health status is changed.
4950
type ApplicationHealthDeploymentReconciler struct {
5051
client.Client
5152
Scheme *runtime.Scheme
5253
Recorder record.EventRecorder
5354
Notification notification.Client
5455
}
5556

56-
//+kubebuilder:rbac:groups=argoproj.io,resources=applications,verbs=get;watch;list;patch
57+
//+kubebuilder:rbac:groups=argoproj.io,resources=applications,verbs=get;watch;list
5758
//+kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;watch;list
59+
//+kubebuilder:rbac:groups=core,resources=events,verbs=create;patch
5860
//+kubebuilder:rbac:groups=argocdcommenter.int128.github.io,resources=applicationhealths,verbs=get;list;watch;create;update;patch
5961
//+kubebuilder:rbac:groups=argocdcommenter.int128.github.io,resources=applicationhealths/status,verbs=get;update;patch
60-
//+kubebuilder:rbac:groups=core,resources=events,verbs=create;patch
6162

6263
func (r *ApplicationHealthDeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
6364
logger := log.FromContext(ctx)
@@ -78,20 +79,19 @@ func (r *ApplicationHealthDeploymentReconciler) Reconcile(ctx context.Context, r
7879
if notification.IsNotFoundError(err) {
7980
// Retry until the application is synced with a valid GitHub Deployment.
8081
// https://github.com/int128/argocd-commenter/issues/762
81-
lastOperationAt := argocd.GetLastOperationAt(app)
82-
if time.Now().Before(lastOperationAt.Add(requeueTimeoutWhenDeploymentNotFound)) {
83-
logger.Info("retry due to deployment not found error", "after", requeueIntervalWhenDeploymentNotFound, "error", err)
82+
lastOperationAt := argocd.GetLastOperationAt(app).Time
83+
if time.Since(lastOperationAt) < requeueTimeoutWhenDeploymentNotFound {
8484
r.Recorder.Eventf(&app, corev1.EventTypeNormal, "DeploymentNotFound",
8585
"deployment %s not found, retry after %s", deploymentURL, requeueIntervalWhenDeploymentNotFound)
8686
return ctrl.Result{RequeueAfter: requeueIntervalWhenDeploymentNotFound}, nil
8787
}
88-
logger.Info("retry timeout because last operation is too old", "lastOperationAt", lastOperationAt)
8988
r.Recorder.Eventf(&app, corev1.EventTypeWarning, "DeploymentNotFoundRetryTimeout",
90-
"deployment %s not found, retry timeout", deploymentURL)
89+
"deployment %s not found but retry timed out", deploymentURL)
9190
return ctrl.Result{}, nil
9291
}
9392
if deploymentIsAlreadyHealthy {
94-
logger.Info("skip notification because the deployment is already healthy", "deployment", deploymentURL)
93+
r.Recorder.Eventf(&app, corev1.EventTypeNormal, "DeploymentAlreadyHealthy",
94+
"skip on status %s because deployment %s is already healthy", app.Status.Health.Status, deploymentURL)
9595
return ctrl.Result{}, nil
9696
}
9797

@@ -101,11 +101,11 @@ func (r *ApplicationHealthDeploymentReconciler) Reconcile(ctx context.Context, r
101101
}
102102

103103
if err := r.Notification.CreateDeploymentStatusOnHealthChanged(ctx, app, argocdURL); err != nil {
104-
logger.Error(err, "unable to create a deployment status")
105-
r.Recorder.Eventf(&app, corev1.EventTypeWarning, "CreateDeploymentError",
106-
"unable to create a deployment status by %s: %s", app.Status.Health.Status, err)
104+
r.Recorder.Eventf(&app, corev1.EventTypeWarning, "CreateDeploymentStatusError",
105+
"unable to create a deployment status on health status %s: %s", app.Status.Health.Status, err)
107106
} else {
108-
r.Recorder.Eventf(&app, corev1.EventTypeNormal, "CreatedDeployment", "created a deployment status by %s", app.Status.Health.Status)
107+
r.Recorder.Eventf(&app, corev1.EventTypeNormal, "CreatedDeploymentStatus",
108+
"created a deployment status on health status %s", app.Status.Health.Status)
109109
}
110110
return ctrl.Result{}, nil
111111
}

internal/controller/applicationphasecomment_controller.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ import (
3232
"sigs.k8s.io/controller-runtime/pkg/log"
3333
)
3434

35-
// ApplicationPhaseCommentReconciler reconciles an Application object
35+
// ApplicationPhaseCommentReconciler reconciles an Application object.
36+
// It creates a comment when the sync operation phase is changed.
3637
type ApplicationPhaseCommentReconciler struct {
3738
client.Client
3839
Scheme *runtime.Scheme
@@ -54,19 +55,22 @@ func (r *ApplicationPhaseCommentReconciler) Reconcile(ctx context.Context, req c
5455
if !app.DeletionTimestamp.IsZero() {
5556
return ctrl.Result{}, nil
5657
}
57-
phase := argocd.GetOperationPhase(app)
58+
phase := argocd.GetSyncOperationPhase(app)
59+
if phase == "" {
60+
return ctrl.Result{}, nil
61+
}
5862

5963
argocdURL, err := argocd.GetExternalURL(ctx, r.Client, req.Namespace)
6064
if err != nil {
6165
logger.Info("unable to determine Argo CD URL", "error", err)
6266
}
6367

6468
if err := r.Notification.CreateCommentsOnPhaseChanged(ctx, app, argocdURL); err != nil {
65-
logger.Error(err, "unable to create a comment")
6669
r.Recorder.Eventf(&app, corev1.EventTypeWarning, "CreateCommentError",
67-
"unable to create a comment by %s: %s", phase, err)
70+
"unable to create a comment on sync operation phase %s: %s", phase, err)
6871
} else {
69-
r.Recorder.Eventf(&app, corev1.EventTypeNormal, "CreatedComment", "created a comment by %s", phase)
72+
r.Recorder.Eventf(&app, corev1.EventTypeNormal, "CreatedComment",
73+
"created a comment on sync operation phase %s", phase)
7074
}
7175
return ctrl.Result{}, nil
7276
}
@@ -84,7 +88,7 @@ func (r *ApplicationPhaseCommentReconciler) SetupWithManager(mgr ctrl.Manager) e
8488
type applicationPhaseCommentFilter struct{}
8589

8690
func (applicationPhaseCommentFilter) Compare(applicationOld, applicationNew argocdv1alpha1.Application) bool {
87-
phaseOld, phaseNew := argocd.GetOperationPhase(applicationOld), argocd.GetOperationPhase(applicationNew)
91+
phaseOld, phaseNew := argocd.GetSyncOperationPhase(applicationOld), argocd.GetSyncOperationPhase(applicationNew)
8892
if phaseNew == "" {
8993
return false
9094
}

internal/controller/applicationphasedeployment_controller.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ import (
3333
"sigs.k8s.io/controller-runtime/pkg/log"
3434
)
3535

36-
// ApplicationPhaseDeploymentReconciler reconciles a ApplicationPhaseDeployment object
36+
// ApplicationPhaseDeploymentReconciler reconciles an Application object.
37+
// It creates a deployment status when the sync operation phase is changed.
3738
type ApplicationPhaseDeploymentReconciler struct {
3839
client.Client
3940
Scheme *runtime.Scheme
@@ -55,7 +56,7 @@ func (r *ApplicationPhaseDeploymentReconciler) Reconcile(ctx context.Context, re
5556
if !app.DeletionTimestamp.IsZero() {
5657
return ctrl.Result{}, nil
5758
}
58-
phase := argocd.GetOperationPhase(app)
59+
phase := argocd.GetSyncOperationPhase(app)
5960
if phase == "" {
6061
return ctrl.Result{}, nil
6162
}
@@ -68,20 +69,19 @@ func (r *ApplicationPhaseDeploymentReconciler) Reconcile(ctx context.Context, re
6869
if notification.IsNotFoundError(err) {
6970
// Retry until the application is synced with a valid GitHub Deployment.
7071
// https://github.com/int128/argocd-commenter/issues/762
71-
lastOperationAt := argocd.GetLastOperationAt(app)
72-
if time.Now().Before(lastOperationAt.Add(requeueTimeoutWhenDeploymentNotFound)) {
73-
logger.Info("retry due to deployment not found error", "after", requeueIntervalWhenDeploymentNotFound, "error", err)
72+
lastOperationAt := argocd.GetLastOperationAt(app).Time
73+
if time.Since(lastOperationAt) < requeueTimeoutWhenDeploymentNotFound {
7474
r.Recorder.Eventf(&app, corev1.EventTypeNormal, "DeploymentNotFound",
7575
"deployment %s not found, retry after %s", deploymentURL, requeueIntervalWhenDeploymentNotFound)
7676
return ctrl.Result{RequeueAfter: requeueIntervalWhenDeploymentNotFound}, nil
7777
}
78-
logger.Info("retry timeout because last operation is too old", "lastOperationAt", lastOperationAt)
7978
r.Recorder.Eventf(&app, corev1.EventTypeWarning, "DeploymentNotFoundRetryTimeout",
80-
"deployment %s not found, retry timeout", deploymentURL)
79+
"deployment %s not found but retry timed out", deploymentURL)
8180
return ctrl.Result{}, nil
8281
}
8382
if deploymentIsAlreadyHealthy {
84-
logger.Info("skip notification because the deployment is already healthy", "deployment", deploymentURL)
83+
r.Recorder.Eventf(&app, corev1.EventTypeNormal, "DeploymentAlreadyHealthy",
84+
"skip on sync operation phase %s because deployment %s is already healthy", phase, deploymentURL)
8585
return ctrl.Result{}, nil
8686
}
8787

@@ -91,11 +91,11 @@ func (r *ApplicationPhaseDeploymentReconciler) Reconcile(ctx context.Context, re
9191
}
9292

9393
if err := r.Notification.CreateDeploymentStatusOnPhaseChanged(ctx, app, argocdURL); err != nil {
94-
logger.Error(err, "unable to create a deployment status")
95-
r.Recorder.Eventf(&app, corev1.EventTypeWarning, "CreateDeploymentError",
96-
"unable to create a deployment status by %s: %s", app.Status.Health.Status, err)
94+
r.Recorder.Eventf(&app, corev1.EventTypeWarning, "CreateDeploymentStatusError",
95+
"unable to create a deployment status on sync operation phase %s: %s", phase, err)
9796
} else {
98-
r.Recorder.Eventf(&app, corev1.EventTypeNormal, "CreatedDeployment", "created a deployment status by %s", app.Status.Health.Status)
97+
r.Recorder.Eventf(&app, corev1.EventTypeNormal, "CreatedDeploymentStatus",
98+
"created a deployment status on sync operation phase %s", phase)
9999
}
100100
return ctrl.Result{}, nil
101101
}
@@ -113,7 +113,7 @@ func (r *ApplicationPhaseDeploymentReconciler) SetupWithManager(mgr ctrl.Manager
113113
type applicationPhaseDeploymentFilter struct{}
114114

115115
func (applicationPhaseDeploymentFilter) Compare(applicationOld, applicationNew argocdv1alpha1.Application) bool {
116-
phaseOld, phaseNew := argocd.GetOperationPhase(applicationOld), argocd.GetOperationPhase(applicationNew)
116+
phaseOld, phaseNew := argocd.GetSyncOperationPhase(applicationOld), argocd.GetSyncOperationPhase(applicationNew)
117117
if phaseNew == "" {
118118
return false
119119
}

internal/controller/suite_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,33 +119,34 @@ var _ = BeforeSuite(func() {
119119
}).SetupWithManager(k8sManager)
120120
Expect(err).ToNot(HaveOccurred())
121121

122-
// comment controllers
123122
err = (&ApplicationPhaseCommentReconciler{
124123
Client: k8sManager.GetClient(),
125124
Scheme: k8sManager.GetScheme(),
126125
Notification: nc,
127126
}).SetupWithManager(k8sManager)
128127
Expect(err).ToNot(HaveOccurred())
128+
129129
err = (&ApplicationHealthCommentReconciler{
130130
Client: k8sManager.GetClient(),
131131
Scheme: k8sManager.GetScheme(),
132132
Notification: nc,
133133
}).SetupWithManager(k8sManager)
134134
Expect(err).ToNot(HaveOccurred())
135135

136-
// deployment controllers
137136
err = (&ApplicationPhaseDeploymentReconciler{
138137
Client: k8sManager.GetClient(),
139138
Scheme: k8sManager.GetScheme(),
140139
Notification: nc,
141140
}).SetupWithManager(k8sManager)
142141
Expect(err).ToNot(HaveOccurred())
142+
143143
err = (&ApplicationHealthDeploymentReconciler{
144144
Client: k8sManager.GetClient(),
145145
Scheme: k8sManager.GetScheme(),
146146
Notification: nc,
147147
}).SetupWithManager(k8sManager)
148148
Expect(err).ToNot(HaveOccurred())
149+
149150
err = (&ApplicationDeletionDeploymentReconciler{
150151
Client: k8sManager.GetClient(),
151152
Scheme: k8sManager.GetScheme(),

0 commit comments

Comments
 (0)