4
4
"context"
5
5
"encoding/base64"
6
6
"fmt"
7
+ "reflect"
7
8
"strings"
8
9
"time"
9
10
@@ -16,16 +17,20 @@ import (
16
17
"github.com/openshift/library-go/pkg/controller/factory"
17
18
"github.com/openshift/library-go/pkg/operator/certrotation"
18
19
"github.com/openshift/library-go/pkg/operator/events"
19
- "github.com/openshift/library-go/pkg/operator/resource/resourceapply"
20
20
"github.com/openshift/library-go/pkg/operator/resource/resourceread"
21
21
"github.com/openshift/library-go/pkg/operator/v1helpers"
22
22
corev1 "k8s.io/api/core/v1"
23
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
23
24
"k8s.io/client-go/kubernetes"
24
25
coreclientv1 "k8s.io/client-go/kubernetes/typed/core/v1"
25
26
corev1listers "k8s.io/client-go/listers/core/v1"
26
27
)
27
28
28
- const workQueueKey = "key"
29
+ const (
30
+ workQueueKey = "key"
31
+ kubeApiserverServerCA = "kube-apiserver-server-ca"
32
+ nodeSystemAdminClient = "node-system-admin-client"
33
+ )
29
34
30
35
type NodeKubeconfigController struct {
31
36
operatorClient v1helpers.StaticPodOperatorClient
@@ -40,24 +45,37 @@ func NewNodeKubeconfigController(
40
45
operatorClient v1helpers.StaticPodOperatorClient ,
41
46
kubeInformersForNamespaces v1helpers.KubeInformersForNamespaces ,
42
47
kubeClient kubernetes.Interface ,
43
- infrastuctureInformer configv1informers.InfrastructureInformer ,
48
+ infrastructureInformer configv1informers.InfrastructureInformer ,
44
49
eventRecorder events.Recorder ,
45
50
) factory.Controller {
46
51
c := & NodeKubeconfigController {
47
52
operatorClient : operatorClient ,
48
53
kubeClient : kubeClient ,
49
54
configMapLister : kubeInformersForNamespaces .ConfigMapLister (),
50
55
secretLister : kubeInformersForNamespaces .SecretLister (),
51
- infrastructureLister : infrastuctureInformer .Lister (),
52
- }
53
-
54
- return factory .New ().WithInformers (
56
+ infrastructureLister : infrastructureInformer .Lister (),
57
+ }
58
+
59
+ return factory .New ().WithFilteredEventsInformers (
60
+ func (obj interface {}) bool {
61
+ if cm , ok := obj .(* corev1.ConfigMap ); ok {
62
+ if cm .Namespace == operatorclient .OperatorNamespace && cm .Name == kubeApiserverServerCA {
63
+ return true
64
+ }
65
+ return false
66
+ }
67
+ if secret , ok := obj .(* corev1.Secret ); ok {
68
+ if secret .Namespace == operatorclient .OperatorNamespace && secret .Name == nodeSystemAdminClient {
69
+ return true
70
+ }
71
+ return false
72
+ }
73
+ return true
74
+ },
55
75
operatorClient .Informer (),
56
- kubeInformersForNamespaces .InformersFor (operatorclient .OperatorNamespace ).Core ().V1 ().ConfigMaps ().Informer (),
57
76
kubeInformersForNamespaces .InformersFor (operatorclient .TargetNamespace ).Core ().V1 ().ConfigMaps ().Informer (),
58
77
kubeInformersForNamespaces .InformersFor (operatorclient .OperatorNamespace ).Core ().V1 ().Secrets ().Informer (),
59
- kubeInformersForNamespaces .InformersFor (operatorclient .TargetNamespace ).Core ().V1 ().Secrets ().Informer (),
60
- infrastuctureInformer .Informer (),
78
+ infrastructureInformer .Informer (),
61
79
).WithSync (c .sync ).WithSyncDegradedOnError (c .operatorClient ).ResyncEvery (5 * time .Minute ).ToController ("NodeKubeconfigController" , eventRecorder .WithComponentSuffix ("node-kubeconfig-controller" ))
62
80
}
63
81
@@ -99,27 +117,27 @@ func (c NodeKubeconfigController) sync(ctx context.Context, syncContext factory.
99
117
func ensureNodeKubeconfigs (ctx context.Context , client coreclientv1.CoreV1Interface , secretLister corev1listers.SecretLister , configmapLister corev1listers.ConfigMapLister , infrastructureLister configv1listers.InfrastructureLister , recorder events.Recorder ) error {
100
118
requiredSecret := resourceread .ReadSecretV1OrDie (bindata .MustAsset ("assets/kube-apiserver/node-kubeconfigs.yaml" ))
101
119
102
- systemAdminCredsSecret , err := secretLister .Secrets (operatorclient .OperatorNamespace ).Get ("node-system-admin-client" )
120
+ systemAdminCredsSecret , err := secretLister .Secrets (operatorclient .OperatorNamespace ).Get (nodeSystemAdminClient )
103
121
if err != nil {
104
122
return err
105
123
}
106
124
107
125
systemAdminClientCert := systemAdminCredsSecret .Data [corev1 .TLSCertKey ]
108
126
if len (systemAdminClientCert ) == 0 {
109
- return fmt .Errorf ("system:admin client certificate missing from secret %s/node-system-admin-client " , operatorclient .OperatorNamespace )
127
+ return fmt .Errorf ("system:admin client certificate missing from secret %s/%s " , operatorclient .OperatorNamespace , nodeSystemAdminClient )
110
128
}
111
129
systemAdminClientKey := systemAdminCredsSecret .Data [corev1 .TLSPrivateKeyKey ]
112
130
if len (systemAdminClientKey ) == 0 {
113
- return fmt .Errorf ("system:admin client private key missing from secret %s/node-system-admin-client " , operatorclient .OperatorNamespace )
131
+ return fmt .Errorf ("system:admin client private key missing from secret %s/%s " , operatorclient .OperatorNamespace , nodeSystemAdminClient )
114
132
}
115
133
116
- servingCABundleCM , err := configmapLister .ConfigMaps (operatorclient .TargetNamespace ).Get ("kube-apiserver-server-ca" )
134
+ servingCABundleCM , err := configmapLister .ConfigMaps (operatorclient .TargetNamespace ).Get (kubeApiserverServerCA )
117
135
if err != nil {
118
136
return err
119
137
}
120
138
servingCABundleData := servingCABundleCM .Data ["ca-bundle.crt" ]
121
139
if len (servingCABundleData ) == 0 {
122
- return fmt .Errorf ("serving CA bundle missing from configmap %s/kube-apiserver-server-ca " , operatorclient .TargetNamespace )
140
+ return fmt .Errorf ("serving CA bundle missing from configmap %s/%s " , operatorclient .TargetNamespace , kubeApiserverServerCA )
123
141
}
124
142
125
143
infrastructure , err := infrastructureLister .Get ("cluster" )
@@ -161,7 +179,16 @@ func ensureNodeKubeconfigs(ctx context.Context, client coreclientv1.CoreV1Interf
161
179
requiredSecret .Annotations [certrotation .CertificateNotAfterAnnotation ] = systemAdminCredsSecret .Annotations [certrotation .CertificateNotAfterAnnotation ]
162
180
}
163
181
164
- _ , _ , err = resourceapply .ApplySecret (ctx , client , recorder , requiredSecret )
182
+ actualSecret , err := secretLister .Secrets (requiredSecret .Namespace ).Get (requiredSecret .Name )
183
+ if ! apierrors .IsNotFound (err ) {
184
+ if err != nil {
185
+ return err
186
+ }
187
+ if reflect .DeepEqual (actualSecret .Data , requiredSecret .Data ) {
188
+ return nil
189
+ }
190
+ }
191
+
165
192
if err != nil {
166
193
return err
167
194
}
0 commit comments