@@ -18,18 +18,23 @@ package healthcheck
18
18
19
19
import (
20
20
"context"
21
- "fmt"
22
21
"time"
23
22
24
23
appsv1 "k8s.io/api/apps/v1"
25
24
corev1 "k8s.io/api/core/v1"
26
- "k8s.io/apimachinery/pkg/runtime"
25
+ "k8s.io/apimachinery/pkg/runtime/schema "
27
26
"k8s.io/apimachinery/pkg/types"
27
+
28
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29
+ "k8s.io/apimachinery/pkg/runtime"
30
+ kerrors "k8s.io/apimachinery/pkg/util/errors"
28
31
operatorv1 "sigs.k8s.io/cluster-api-operator/api/v1alpha2"
29
32
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
30
33
"sigs.k8s.io/cluster-api/util/conditions"
31
34
"sigs.k8s.io/cluster-api/util/patch"
32
35
ctrl "sigs.k8s.io/controller-runtime"
36
+
37
+ utilruntime "k8s.io/apimachinery/pkg/util/runtime"
33
38
"sigs.k8s.io/controller-runtime/pkg/builder"
34
39
"sigs.k8s.io/controller-runtime/pkg/client"
35
40
"sigs.k8s.io/controller-runtime/pkg/controller"
@@ -38,22 +43,76 @@ import (
38
43
"sigs.k8s.io/controller-runtime/pkg/reconcile"
39
44
)
40
45
46
+ func init () {
47
+ var err error
48
+ deploymentPredicate , err = predicate .LabelSelectorPredicate (metav1.LabelSelector {
49
+ MatchExpressions : []metav1.LabelSelectorRequirement {{
50
+ Key : providerLabelKey ,
51
+ Operator : metav1 .LabelSelectorOpExists ,
52
+ }},
53
+ })
54
+ utilruntime .Must (err )
55
+ }
56
+
57
+ const providerLabelKey = "cluster.x-k8s.io/provider"
58
+
59
+ var deploymentPredicate predicate.Predicate
60
+
41
61
type ProviderHealthCheckReconciler struct {
42
62
Client client.Client
43
63
}
44
64
45
- const (
46
- providerLabelKey = "cluster.x-k8s.io/provider"
47
- )
65
+ type GenericProviderHealthCheckReconciler struct {
66
+ Client client.Client
67
+ Provider operatorv1.GenericProvider
68
+ providerGVK schema.GroupVersionKind
69
+ }
48
70
49
71
func (r * ProviderHealthCheckReconciler ) SetupWithManager (mgr ctrl.Manager , options controller.Options ) error {
72
+ return kerrors .NewAggregate ([]error {
73
+ (& GenericProviderHealthCheckReconciler {
74
+ Client : mgr .GetClient (),
75
+ Provider : & operatorv1.CoreProvider {},
76
+ }).SetupWithManager (mgr , options ),
77
+ (& GenericProviderHealthCheckReconciler {
78
+ Client : mgr .GetClient (),
79
+ Provider : & operatorv1.InfrastructureProvider {},
80
+ }).SetupWithManager (mgr , options ),
81
+ (& GenericProviderHealthCheckReconciler {
82
+ Client : mgr .GetClient (),
83
+ Provider : & operatorv1.BootstrapProvider {},
84
+ }).SetupWithManager (mgr , options ),
85
+ (& GenericProviderHealthCheckReconciler {
86
+ Client : mgr .GetClient (),
87
+ Provider : & operatorv1.ControlPlaneProvider {},
88
+ }).SetupWithManager (mgr , options ),
89
+ (& GenericProviderHealthCheckReconciler {
90
+ Client : mgr .GetClient (),
91
+ Provider : & operatorv1.AddonProvider {},
92
+ }).SetupWithManager (mgr , options ),
93
+ (& GenericProviderHealthCheckReconciler {
94
+ Client : mgr .GetClient (),
95
+ Provider : & operatorv1.IPAMProvider {},
96
+ }).SetupWithManager (mgr , options ),
97
+ })
98
+ }
99
+
100
+ func (r * GenericProviderHealthCheckReconciler ) SetupWithManager (mgr ctrl.Manager , options controller.Options ) error {
101
+ kinds , _ , err := r .Client .Scheme ().ObjectKinds (r .Provider )
102
+ if err != nil {
103
+ return err
104
+ }
105
+
106
+ r .providerGVK = kinds [0 ]
107
+
50
108
return ctrl .NewControllerManagedBy (mgr ).
51
- For (& appsv1.Deployment {}, builder .WithPredicates (providerDeploymentPredicates ())).
109
+ For (& appsv1.Deployment {}, builder .WithPredicates (r .providerDeploymentPredicates ())).
110
+ WithEventFilter (deploymentPredicate ).
52
111
WithOptions (options ).
53
112
Complete (r )
54
113
}
55
114
56
- func (r * ProviderHealthCheckReconciler ) Reconcile (ctx context.Context , req reconcile.Request ) (_ reconcile.Result , reterr error ) {
115
+ func (r * GenericProviderHealthCheckReconciler ) Reconcile (ctx context.Context , req reconcile.Request ) (_ reconcile.Result , reterr error ) {
57
116
log := ctrl .LoggerFrom (ctx )
58
117
59
118
log .Info ("Checking provider health" )
@@ -67,19 +126,15 @@ func (r *ProviderHealthCheckReconciler) Reconcile(ctx context.Context, req recon
67
126
return result , err
68
127
}
69
128
70
- // There should be just one owner reference - to a Provider resource.
71
- if len (deployment .GetOwnerReferences ()) != 1 {
72
- return result , fmt .Errorf ("incorrect number of owner references for provider deployment %s" , req .NamespacedName )
129
+ // There should be one owner pointing to the Provider resource.
130
+ if err := r .Client .Get (ctx , r .getProviderKey (deployment ), r .Provider ); err != nil {
131
+ // Error reading the object - requeue the request.
132
+ return result , err
73
133
}
74
134
75
- deploymentOwner := deployment .GetOwnerReferences ()[0 ]
76
-
77
135
deploymentAvailableCondition := getDeploymentCondition (deployment .Status , appsv1 .DeploymentAvailable )
78
136
79
- typedProvider , err := r .getGenericProvider (ctx , deploymentOwner .Kind , deploymentOwner .Name , req .Namespace )
80
- if err != nil {
81
- return result , err
82
- }
137
+ typedProvider := r .Provider
83
138
84
139
// Stop earlier if this provider is not fully installed yet.
85
140
if ! conditions .IsTrue (typedProvider , operatorv1 .ProviderInstalledCondition ) {
@@ -122,52 +177,20 @@ func (r *ProviderHealthCheckReconciler) Reconcile(ctx context.Context, req recon
122
177
return result , patchHelper .Patch (ctx , typedProvider , options )
123
178
}
124
179
125
- func (r * ProviderHealthCheckReconciler ) getGenericProvider (ctx context.Context , providerKind , providerName , providerNamespace string ) (operatorv1.GenericProvider , error ) {
126
- switch providerKind {
127
- case "CoreProvider" :
128
- provider := & operatorv1.CoreProvider {}
129
- if err := r .Client .Get (ctx , types.NamespacedName {Name : providerName , Namespace : providerNamespace }, provider ); err != nil {
130
- return nil , err
131
- }
132
-
133
- return provider , nil
134
- case "BootstrapProvider" :
135
- provider := & operatorv1.BootstrapProvider {}
136
- if err := r .Client .Get (ctx , types.NamespacedName {Name : providerName , Namespace : providerNamespace }, provider ); err != nil {
137
- return nil , err
138
- }
139
-
140
- return provider , nil
141
- case "ControlPlaneProvider" :
142
- provider := & operatorv1.ControlPlaneProvider {}
143
- if err := r .Client .Get (ctx , types.NamespacedName {Name : providerName , Namespace : providerNamespace }, provider ); err != nil {
144
- return nil , err
145
- }
146
-
147
- return provider , nil
148
- case "InfrastructureProvider" :
149
- provider := & operatorv1.InfrastructureProvider {}
150
- if err := r .Client .Get (ctx , types.NamespacedName {Name : providerName , Namespace : providerNamespace }, provider ); err != nil {
151
- return nil , err
152
- }
153
-
154
- return provider , nil
155
- case "AddonProvider" :
156
- provider := & operatorv1.AddonProvider {}
157
- if err := r .Client .Get (ctx , types.NamespacedName {Name : providerName , Namespace : providerNamespace }, provider ); err != nil {
158
- return nil , err
180
+ func (r * GenericProviderHealthCheckReconciler ) getProviderName (deploy client.Object ) string {
181
+ for _ , owner := range deploy .GetOwnerReferences () {
182
+ if owner .Kind == r .providerGVK .Kind {
183
+ return owner .Name
159
184
}
185
+ }
160
186
161
- return provider , nil
162
- case "IPAMProvider" :
163
- provider := & operatorv1.IPAMProvider {}
164
- if err := r .Client .Get (ctx , types.NamespacedName {Name : providerName , Namespace : providerNamespace }, provider ); err != nil {
165
- return nil , err
166
- }
187
+ return ""
188
+ }
167
189
168
- return provider , nil
169
- default :
170
- return nil , fmt .Errorf ("failed to cast interface for type: %s" , providerKind )
190
+ func (r * GenericProviderHealthCheckReconciler ) getProviderKey (deploy client.Object ) types.NamespacedName {
191
+ return types.NamespacedName {
192
+ Namespace : deploy .GetNamespace (),
193
+ Name : r .getProviderName (deploy ),
171
194
}
172
195
}
173
196
@@ -183,16 +206,14 @@ func getDeploymentCondition(status appsv1.DeploymentStatus, condType appsv1.Depl
183
206
return nil
184
207
}
185
208
186
- func providerDeploymentPredicates () predicate.Funcs {
209
+ func ( r * GenericProviderHealthCheckReconciler ) providerDeploymentPredicates () predicate.Funcs {
187
210
isProviderDeployment := func (obj runtime.Object ) bool {
188
- clusterOperator , ok := obj .(* appsv1.Deployment )
211
+ deployment , ok := obj .(* appsv1.Deployment )
189
212
if ! ok {
190
213
panic ("expected to get an of object of type appsv1.Deployment" )
191
214
}
192
215
193
- _ , found := clusterOperator .GetLabels ()[providerLabelKey ]
194
-
195
- return found
216
+ return r .getProviderName (deployment ) != ""
196
217
}
197
218
198
219
return predicate.Funcs {
0 commit comments