7
7
"strconv"
8
8
"time"
9
9
10
+ clusterv1alpha1 "github.com/oam-dev/cluster-gateway/pkg/apis/cluster/v1alpha1"
10
11
proxyv1alpha1 "github.com/oam-dev/cluster-gateway/pkg/apis/proxy/v1alpha1"
11
12
"github.com/oam-dev/cluster-gateway/pkg/common"
12
13
"github.com/oam-dev/cluster-gateway/pkg/event"
@@ -28,6 +29,7 @@ import (
28
29
appsv1 "k8s.io/api/apps/v1"
29
30
apierrors "k8s.io/apimachinery/pkg/api/errors"
30
31
addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
32
+ ocmauthv1alpha1 "open-cluster-management.io/managed-serviceaccount/api/v1alpha1"
31
33
"sigs.k8s.io/controller-runtime/pkg/cache"
32
34
"sigs.k8s.io/controller-runtime/pkg/client"
33
35
"sigs.k8s.io/controller-runtime/pkg/reconcile"
@@ -55,6 +57,11 @@ func SetupClusterGatewayInstallerWithManager(mgr ctrl.Manager, caPair *crypto.CA
55
57
& event.ClusterGatewayConfigurationHandler {
56
58
Client : mgr .GetClient (),
57
59
}).
60
+ Watches (
61
+ & source.Kind {
62
+ Type : & corev1.Secret {},
63
+ },
64
+ & event.SecretHandler {}).
58
65
Complete (installer )
59
66
}
60
67
@@ -81,6 +88,11 @@ func (c *ClusterGatewayInstaller) Reconcile(ctx context.Context, request reconci
81
88
}
82
89
return reconcile.Result {}, errors .Wrapf (err , "failed to get cluster-management-addon: %v" , request .Name )
83
90
}
91
+ if addon .Name != common .AddonName {
92
+ // skip
93
+ return reconcile.Result {}, nil
94
+ }
95
+
84
96
if addon .Spec .AddOnConfiguration .CRDName != common .ClusterGatewayConfigurationCRDName {
85
97
// skip
86
98
return reconcile.Result {}, nil
@@ -102,9 +114,12 @@ func (c *ClusterGatewayInstaller) Reconcile(ctx context.Context, request reconci
102
114
if err := c .ensureNamespace (clusterGatewayConfiguration .Spec .SecretNamespace ); err != nil {
103
115
return reconcile.Result {}, errors .Wrapf (err , "failed to ensure required namespace" )
104
116
}
105
- if err := c .ensureProxySecrets (clusterGatewayConfiguration ); err != nil {
117
+ if err := c .ensureClusterProxySecrets (clusterGatewayConfiguration ); err != nil {
106
118
return reconcile.Result {}, errors .Wrapf (err , "failed to ensure required proxy client related credentials" )
107
119
}
120
+ if err := c .ensureSecretManagement (addon , clusterGatewayConfiguration ); err != nil {
121
+ return reconcile.Result {}, errors .Wrapf (err , "failed to configure secret management" )
122
+ }
108
123
109
124
sans := []string {
110
125
ServiceNameClusterGateway ,
@@ -196,7 +211,7 @@ func (c *ClusterGatewayInstaller) ensureAPIService(addon *addonv1alpha1.ClusterM
196
211
return nil
197
212
}
198
213
199
- func (c * ClusterGatewayInstaller ) ensureProxySecrets (config * proxyv1alpha1.ClusterGatewayConfiguration ) error {
214
+ func (c * ClusterGatewayInstaller ) ensureClusterProxySecrets (config * proxyv1alpha1.ClusterGatewayConfiguration ) error {
200
215
if config .Spec .Egress .Type != proxyv1alpha1 .EgressTypeClusterProxy {
201
216
return nil
202
217
}
@@ -232,6 +247,106 @@ func (c *ClusterGatewayInstaller) ensureProxySecrets(config *proxyv1alpha1.Clust
232
247
return nil
233
248
}
234
249
250
+ func (c * ClusterGatewayInstaller ) ensureSecretManagement (clusterAddon * addonv1alpha1.ClusterManagementAddOn , config * proxyv1alpha1.ClusterGatewayConfiguration ) error {
251
+ if config .Spec .SecretManagement .Type != proxyv1alpha1 .SecretManagementTypeManagedServiceAccount {
252
+ return nil
253
+ }
254
+ addonList := & addonv1alpha1.ManagedClusterAddOnList {}
255
+ if err := c .client .List (context .TODO (), addonList ); err != nil {
256
+ return errors .Wrapf (err , "failed to list managed cluster addons" )
257
+ }
258
+ clusterGatewayAddon := make ([]* addonv1alpha1.ManagedClusterAddOn , 0 )
259
+ for _ , addon := range addonList .Items {
260
+ addon := addon
261
+ if addon .Name == common .AddonName {
262
+ clusterGatewayAddon = append (clusterGatewayAddon , & addon )
263
+ }
264
+ }
265
+ for _ , addon := range clusterGatewayAddon {
266
+ managedServiceAccount := buildManagedServiceAccount (addon )
267
+ if err := c .client .Create (context .TODO (), managedServiceAccount ); err != nil {
268
+ if ! apierrors .IsAlreadyExists (err ) {
269
+ return errors .Wrapf (err , "failed to create managed serviceaccount" )
270
+ }
271
+ }
272
+
273
+ if err := c .copySecretForManagedServiceAccount (
274
+ clusterAddon ,
275
+ config ,
276
+ addon .Namespace ); err != nil {
277
+ return errors .Wrapf (err , "failed to copy secret from managed serviceaccount" )
278
+ }
279
+ }
280
+ return nil
281
+ }
282
+
283
+ func (c * ClusterGatewayInstaller ) copySecretForManagedServiceAccount (addon * addonv1alpha1.ClusterManagementAddOn , config * proxyv1alpha1.ClusterGatewayConfiguration , clusterName string ) error {
284
+ endpointType := clusterv1alpha1 .ClusterEndpointTypeConst
285
+ if config .Spec .Egress .Type == proxyv1alpha1 .EgressTypeClusterProxy {
286
+ endpointType = clusterv1alpha1 .ClusterEndpointTypeClusterProxy
287
+ }
288
+ gatewaySecretNamespace := config .Spec .SecretNamespace
289
+ secretName := config .Spec .SecretManagement .ManagedServiceAccount .Name
290
+
291
+ secret , err := c .secretLister .Secrets (clusterName ).
292
+ Get (secretName )
293
+ if err != nil {
294
+ if ! apierrors .IsNotFound (err ) {
295
+ return errors .Wrapf (err , "failed to get token secret" )
296
+ }
297
+ return nil
298
+ }
299
+ currentSecret , err := c .secretLister .Secrets (gatewaySecretNamespace ).Get (clusterName )
300
+ shouldCreate := false
301
+ if err != nil {
302
+ if ! apierrors .IsNotFound (err ) {
303
+ return errors .Wrapf (err , "failed to get the cluster secret" )
304
+ }
305
+ shouldCreate = true
306
+ }
307
+ if shouldCreate {
308
+ if _ , err := c .nativeClient .CoreV1 ().Secrets (gatewaySecretNamespace ).
309
+ Create (context .TODO (),
310
+ & corev1.Secret {
311
+ ObjectMeta : metav1.ObjectMeta {
312
+ Namespace : gatewaySecretNamespace ,
313
+ Name : clusterName ,
314
+ Labels : map [string ]string {
315
+ clusterv1alpha1 .LabelKeyClusterCredentialType : string (clusterv1alpha1 .CredentialTypeServiceAccountToken ),
316
+ clusterv1alpha1 .LabelKeyClusterEndpointType : endpointType ,
317
+ },
318
+ OwnerReferences : []metav1.OwnerReference {
319
+ {
320
+ APIVersion : addonv1alpha1 .GroupVersion .String (),
321
+ Kind : "ClusterManagementAddOn" ,
322
+ UID : addon .UID ,
323
+ Name : addon .Name ,
324
+ },
325
+ },
326
+ },
327
+ Type : corev1 .SecretTypeOpaque ,
328
+ Data : map [string ][]byte {
329
+ corev1 .ServiceAccountRootCAKey : secret .Data [corev1 .ServiceAccountRootCAKey ],
330
+ corev1 .ServiceAccountTokenKey : secret .Data [corev1 .ServiceAccountTokenKey ],
331
+ },
332
+ },
333
+ metav1.CreateOptions {}); err != nil {
334
+ return errors .Wrapf (err , "failed to create the cluster secret" )
335
+ }
336
+ } else {
337
+ if bytes .Equal (secret .Data [corev1 .ServiceAccountTokenKey ], currentSecret .Data [corev1 .ServiceAccountTokenKey ]) {
338
+ return nil // no need for an update
339
+ }
340
+ currentSecret .Data [corev1 .ServiceAccountRootCAKey ] = secret .Data [corev1 .ServiceAccountRootCAKey ]
341
+ currentSecret .Data [corev1 .ServiceAccountTokenKey ] = secret .Data [corev1 .ServiceAccountTokenKey ]
342
+ if _ , err := c .nativeClient .CoreV1 ().Secrets (gatewaySecretNamespace ).
343
+ Update (context .TODO (), currentSecret , metav1.UpdateOptions {}); err != nil {
344
+ return errors .Wrapf (err , "failed to update the cluster secret" )
345
+ }
346
+ }
347
+ return nil
348
+ }
349
+
235
350
func newServiceAccount (addon * addonv1alpha1.ClusterManagementAddOn , namespace string ) * corev1.ServiceAccount {
236
351
return & corev1.ServiceAccount {
237
352
TypeMeta : metav1.TypeMeta {
@@ -567,5 +682,33 @@ func newAPFClusterRoleBinding(addon *addonv1alpha1.ClusterManagementAddOn, names
567
682
},
568
683
},
569
684
}
685
+ }
570
686
687
+ func buildManagedServiceAccount (addon * addonv1alpha1.ManagedClusterAddOn ) * ocmauthv1alpha1.ManagedServiceAccount {
688
+ return & ocmauthv1alpha1.ManagedServiceAccount {
689
+ TypeMeta : metav1.TypeMeta {
690
+ APIVersion : "authentication.open-cluster-management.io/v1alpha1" ,
691
+ Kind : "ManagedServiceAccount" ,
692
+ },
693
+ ObjectMeta : metav1.ObjectMeta {
694
+ Namespace : addon .Namespace ,
695
+ Name : common .AddonName ,
696
+ OwnerReferences : []metav1.OwnerReference {
697
+ {
698
+ APIVersion : addonv1alpha1 .GroupVersion .String (),
699
+ Kind : "ManagedClusterAddOn" ,
700
+ UID : addon .UID ,
701
+ Name : addon .Name ,
702
+ },
703
+ },
704
+ },
705
+ Spec : ocmauthv1alpha1.ManagedServiceAccountSpec {
706
+ Rotation : ocmauthv1alpha1.ManagedServiceAccountRotation {
707
+ Enabled : true ,
708
+ Validity : metav1.Duration {
709
+ Duration : time .Hour * 24 * 180 ,
710
+ },
711
+ },
712
+ },
713
+ }
571
714
}
0 commit comments