@@ -19,6 +19,7 @@ import (
19
19
"encoding/json"
20
20
"errors"
21
21
"os"
22
+ "time"
22
23
23
24
"github.com/operator-framework/operator-sdk/pkg/ansible/events"
24
25
"github.com/operator-framework/operator-sdk/pkg/ansible/proxy/kubeconfig"
@@ -34,12 +35,20 @@ import (
34
35
"sigs.k8s.io/controller-runtime/pkg/reconcile"
35
36
)
36
37
38
+ const (
39
+ // ReconcilePeriodAnnotation - annotation used by a user to specify the reconcilation interval for the CR.
40
+ // To use create a CR with an annotation "ansible.operator-sdk/reconcile-period: 30s" or some other valid
41
+ // Duration. This will override the operators/or controllers reconcile period for that particular CR.
42
+ ReconcilePeriodAnnotation = "ansible.operator-sdk/reconcile-period"
43
+ )
44
+
37
45
// AnsibleOperatorReconciler - object to reconcile runner requests
38
46
type AnsibleOperatorReconciler struct {
39
- GVK schema.GroupVersionKind
40
- Runner runner.Runner
41
- Client client.Client
42
- EventHandlers []events.EventHandler
47
+ GVK schema.GroupVersionKind
48
+ Runner runner.Runner
49
+ Client client.Client
50
+ EventHandlers []events.EventHandler
51
+ ReconcilePeriod time.Duration
43
52
}
44
53
45
54
// Reconcile - handle the event.
@@ -53,6 +62,14 @@ func (r *AnsibleOperatorReconciler) Reconcile(request reconcile.Request) (reconc
53
62
if err != nil {
54
63
return reconcile.Result {}, err
55
64
}
65
+ reconcileResult := reconcile.Result {RequeueAfter : r .ReconcilePeriod }
66
+ if ds , ok := u .GetAnnotations ()[ReconcilePeriodAnnotation ]; ok {
67
+ duration , err := time .ParseDuration (ds )
68
+ if err != nil {
69
+ return reconcileResult , err
70
+ }
71
+ reconcileResult .RequeueAfter = duration
72
+ }
56
73
57
74
deleted := u .GetDeletionTimestamp () != nil
58
75
finalizer , finalizerExists := r .Runner .GetFinalizer ()
@@ -63,11 +80,11 @@ func (r *AnsibleOperatorReconciler) Reconcile(request reconcile.Request) (reconc
63
80
finalizers := append (pendingFinalizers , finalizer )
64
81
u .SetFinalizers (finalizers )
65
82
err := r .Client .Update (context .TODO (), u )
66
- return reconcile. Result {} , err
83
+ return reconcileResult , err
67
84
}
68
85
if ! contains (pendingFinalizers , finalizer ) && deleted {
69
86
logrus .Info ("Resource is terminated, skipping reconcilation" )
70
- return reconcile. Result {} , nil
87
+ return reconcileResult , nil
71
88
}
72
89
73
90
spec := u .Object ["spec" ]
@@ -77,9 +94,10 @@ func (r *AnsibleOperatorReconciler) Reconcile(request reconcile.Request) (reconc
77
94
u .Object ["spec" ] = map [string ]interface {}{}
78
95
err = r .Client .Update (context .TODO (), u )
79
96
if err != nil {
80
- return reconcile. Result {} , err
97
+ return reconcileResult , err
81
98
}
82
- return reconcile.Result {Requeue : true }, nil
99
+ reconcileResult .Requeue = true
100
+ return reconcileResult , nil
83
101
}
84
102
status := u .Object ["status" ]
85
103
_ , ok = status .(map [string ]interface {})
@@ -88,9 +106,10 @@ func (r *AnsibleOperatorReconciler) Reconcile(request reconcile.Request) (reconc
88
106
u .Object ["status" ] = map [string ]interface {}{}
89
107
err = r .Client .Update (context .TODO (), u )
90
108
if err != nil {
91
- return reconcile. Result {} , err
109
+ return reconcileResult , err
92
110
}
93
- return reconcile.Result {Requeue : true }, nil
111
+ reconcileResult .Requeue = true
112
+ return reconcileResult , nil
94
113
}
95
114
96
115
// If status is an empty map we can assume CR was just created
@@ -101,9 +120,10 @@ func (r *AnsibleOperatorReconciler) Reconcile(request reconcile.Request) (reconc
101
120
}
102
121
err = r .Client .Update (context .TODO (), u )
103
122
if err != nil {
104
- return reconcile. Result {} , err
123
+ return reconcileResult , err
105
124
}
106
- return reconcile.Result {Requeue : true }, nil
125
+ reconcileResult .Requeue = true
126
+ return reconcileResult , nil
107
127
}
108
128
109
129
ownerRef := metav1.OwnerReference {
@@ -115,12 +135,12 @@ func (r *AnsibleOperatorReconciler) Reconcile(request reconcile.Request) (reconc
115
135
116
136
kc , err := kubeconfig .Create (ownerRef , "http://localhost:8888" , u .GetNamespace ())
117
137
if err != nil {
118
- return reconcile. Result {} , err
138
+ return reconcileResult , err
119
139
}
120
140
defer os .Remove (kc .Name ())
121
141
eventChan , err := r .Runner .Run (u , kc .Name ())
122
142
if err != nil {
123
- return reconcile. Result {} , err
143
+ return reconcileResult , err
124
144
}
125
145
126
146
// iterate events from ansible, looking for the final one
@@ -144,7 +164,7 @@ func (r *AnsibleOperatorReconciler) Reconcile(request reconcile.Request) (reconc
144
164
if statusEvent .Event == "" {
145
165
err := errors .New ("did not receive playbook_on_stats event" )
146
166
logrus .Error (err .Error ())
147
- return reconcile. Result {} , err
167
+ return reconcileResult , err
148
168
}
149
169
150
170
// We only want to update the CustomResource once, so we'll track changes and do it at the end
@@ -186,9 +206,10 @@ func (r *AnsibleOperatorReconciler) Reconcile(request reconcile.Request) (reconc
186
206
err = r .Client .Update (context .TODO (), u )
187
207
}
188
208
if ! runSuccessful {
189
- return reconcile.Result {Requeue : true }, err
209
+ reconcileResult .Requeue = true
210
+ return reconcileResult , err
190
211
}
191
- return reconcile. Result {} , err
212
+ return reconcileResult , err
192
213
}
193
214
194
215
func contains (l []string , s string ) bool {
0 commit comments