@@ -11,14 +11,17 @@ import (
11
11
12
12
corev1 "k8s.io/api/core/v1"
13
13
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
14
+ "k8s.io/apimachinery/pkg/api/errors"
14
15
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
15
16
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
16
17
apiserverv1 "k8s.io/apiserver/pkg/apis/config/v1"
18
+ clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
17
19
cabpkv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
18
20
controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1"
19
21
runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
20
22
ctrl "sigs.k8s.io/controller-runtime"
21
23
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
24
+ "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
22
25
"sigs.k8s.io/yaml"
23
26
24
27
carenv1 "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/v1alpha1"
@@ -27,7 +30,7 @@ import (
27
30
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/patches/selectors"
28
31
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/variables"
29
32
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/utils"
30
- "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/k8s/client"
33
+ k8sClientUtil "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/k8s/client"
31
34
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig"
32
35
)
33
36
@@ -40,33 +43,19 @@ const (
40
43
apiServerEncryptionConfigArg = "encryption-provider-config"
41
44
)
42
45
43
- type Config struct {
44
- Client ctrlclient.Client
45
- AESSecretKeyGenerator TokenGenerator
46
- }
47
-
48
46
type encryptionPatchHandler struct {
49
- config * Config
47
+ client ctrlclient.Client
48
+ keyGenerator TokenGenerator
50
49
variableName string
51
50
variableFieldPath []string
52
51
}
53
52
54
- func NewPatch (config * Config ) * encryptionPatchHandler {
55
- return newEncryptionPatchHandler (
56
- config ,
57
- clusterconfig .MetaVariableName ,
58
- VariableName )
59
- }
60
-
61
- func newEncryptionPatchHandler (
62
- config * Config ,
63
- variableName string ,
64
- variableFieldPath ... string ,
65
- ) * encryptionPatchHandler {
53
+ func NewPatch (client ctrlclient.Client , keyGenerator TokenGenerator ) * encryptionPatchHandler {
66
54
return & encryptionPatchHandler {
67
- config : config ,
68
- variableName : variableName ,
69
- variableFieldPath : variableFieldPath ,
55
+ client : client ,
56
+ keyGenerator : keyGenerator ,
57
+ variableName : clusterconfig .MetaVariableName ,
58
+ variableFieldPath : []string {VariableName },
70
59
}
71
60
}
72
61
@@ -76,7 +65,7 @@ func (h *encryptionPatchHandler) Mutate(
76
65
vars map [string ]apiextensionsv1.JSON ,
77
66
holderRef runtimehooksv1.HolderReference ,
78
67
clusterKey ctrlclient.ObjectKey ,
79
- _ mutation.ClusterGetter ,
68
+ clusterGetter mutation.ClusterGetter ,
80
69
) error {
81
70
log := ctrl .LoggerFrom (ctx , "holderRef" , holderRef )
82
71
@@ -102,25 +91,49 @@ func (h *encryptionPatchHandler) Mutate(
102
91
encryptionVariable ,
103
92
)
104
93
94
+ cluster , err := clusterGetter (ctx )
95
+ if err != nil {
96
+ log .Error (err , "failed to get cluster from encryption mutation handler" )
97
+ return err
98
+ }
99
+
100
+ found , err := h .DefaultEncryptionSecretExists (ctx , cluster )
101
+ if err != nil {
102
+ log .WithValues (
103
+ "defaultEncryptionSecret" , defaultEncryptionSecretName (cluster .Name ),
104
+ ).Error (err , "failed to find default encryption configuration secret" )
105
+ return err
106
+ }
107
+ // we do not rotate or override the secret keys for encryption configuration
108
+ if found {
109
+ log .V (5 ).WithValues (
110
+ "defaultEncryptionSecret" , defaultEncryptionSecretName (cluster .Name ),
111
+ ).Info (
112
+ "skip generating encryption configuration. Default encryption configuration secret exists" ,
113
+ defaultEncryptionSecretName (cluster .Name ))
114
+ return nil
115
+ }
116
+
105
117
return patches .MutateIfApplicable (
106
118
obj , vars , & holderRef , selectors .ControlPlane (), log ,
107
119
func (obj * controlplanev1.KubeadmControlPlaneTemplate ) error {
108
120
log .WithValues (
109
121
"patchedObjectKind" , obj .GetObjectKind ().GroupVersionKind ().String (),
110
122
"patchedObjectName" , ctrlclient .ObjectKeyFromObject (obj ),
111
- ).Info ("setting encryption in control plane kubeadm config template " )
123
+ ).Info ("adding encryption configuration files and API server extra args in control plane kubeadm config spec " )
112
124
encConfig , err := h .generateEncryptionConfiguration (encryptionVariable .Providers )
113
125
if err != nil {
114
126
return err
115
127
}
116
- secretName , err := h . CreateEncryptionConfigurationSecret ( ctx , encConfig , clusterKey )
117
- if err != nil {
128
+
129
+ if err := h . CreateEncryptionConfigurationSecret ( ctx , encConfig , cluster ); err != nil {
118
130
return err
119
131
}
132
+
120
133
// Create kubadm config file for encryption config
121
134
obj .Spec .Template .Spec .KubeadmConfigSpec .Files = append (
122
135
obj .Spec .Template .Spec .KubeadmConfigSpec .Files ,
123
- generateEncryptionCredentialsFile (secretName ))
136
+ generateEncryptionCredentialsFile (cluster ))
124
137
125
138
// set APIServer args for encryption config
126
139
if obj .Spec .Template .Spec .KubeadmConfigSpec .ClusterConfiguration == nil {
@@ -136,7 +149,8 @@ func (h *encryptionPatchHandler) Mutate(
136
149
})
137
150
}
138
151
139
- func generateEncryptionCredentialsFile (secretName string ) cabpkv1.File {
152
+ func generateEncryptionCredentialsFile (cluster * clusterv1.Cluster ) cabpkv1.File {
153
+ secretName := defaultEncryptionSecretName (cluster .Name )
140
154
return cabpkv1.File {
141
155
Path : encryptionConfigurationOnRemote ,
142
156
ContentFrom : & cabpkv1.FileSource {
@@ -155,7 +169,7 @@ func (h *encryptionPatchHandler) generateEncryptionConfiguration(
155
169
// We only support encryption for "secrets" and "configmaps" using "aescbc" provider.
156
170
resourceConfig , err := encryptionConfigForSecretsAndConfigMaps (
157
171
providers ,
158
- h .config . AESSecretKeyGenerator ,
172
+ h .keyGenerator ,
159
173
)
160
174
if err != nil {
161
175
return nil , err
@@ -171,39 +185,71 @@ func (h *encryptionPatchHandler) generateEncryptionConfiguration(
171
185
}, nil
172
186
}
173
187
188
+ func (h * encryptionPatchHandler ) DefaultEncryptionSecretExists (
189
+ ctx context.Context ,
190
+ cluster * clusterv1.Cluster ,
191
+ ) (bool , error ) {
192
+ secretName := defaultEncryptionSecretName (cluster .Name )
193
+ existingSecret := & corev1.Secret {
194
+ TypeMeta : metav1.TypeMeta {
195
+ APIVersion : corev1 .SchemeGroupVersion .String (),
196
+ Kind : "Secret" ,
197
+ },
198
+ ObjectMeta : metav1.ObjectMeta {
199
+ Name : secretName ,
200
+ Namespace : cluster .Namespace ,
201
+ },
202
+ }
203
+ err := h .client .Get (ctx , ctrlclient .ObjectKeyFromObject (existingSecret ), existingSecret )
204
+ if err != nil {
205
+ if errors .IsNotFound (err ) {
206
+ return false , nil
207
+ }
208
+ return false , err
209
+ }
210
+ return true , nil
211
+ }
212
+
174
213
func (h * encryptionPatchHandler ) CreateEncryptionConfigurationSecret (
175
214
ctx context.Context ,
176
215
encryptionConfig * apiserverv1.EncryptionConfiguration ,
177
- clusterKey ctrlclient. ObjectKey ,
178
- ) ( string , error ) {
216
+ cluster * clusterv1. Cluster ,
217
+ ) error {
179
218
dataYaml , err := yaml .Marshal (encryptionConfig )
180
219
if err != nil {
181
- return "" , fmt .Errorf ("unable to marshal encryption configuration to YAML: %w" , err )
220
+ return fmt .Errorf ("unable to marshal encryption configuration to YAML: %w" , err )
182
221
}
183
222
184
223
secretData := map [string ]string {
185
224
SecretKeyForEtcdEncryption : strings .TrimSpace (string (dataYaml )),
186
225
}
187
- secretName := defaultEncryptionSecretName (clusterKey .Name )
226
+ secretName := defaultEncryptionSecretName (cluster .Name )
188
227
encryptionConfigSecret := & corev1.Secret {
189
228
TypeMeta : metav1.TypeMeta {
190
- APIVersion : "v1" ,
229
+ APIVersion : corev1 . SchemeGroupVersion . String () ,
191
230
Kind : "Secret" ,
192
231
},
193
232
ObjectMeta : metav1.ObjectMeta {
194
233
Name : secretName ,
195
- Namespace : clusterKey .Namespace ,
196
- Labels : utils .NewLabels (utils .WithMove (), utils .WithClusterName (clusterKey .Name )),
234
+ Namespace : cluster .Namespace ,
235
+ Labels : utils .NewLabels (utils .WithMove (), utils .WithClusterName (cluster .Name )),
197
236
},
198
237
StringData : secretData ,
199
238
Type : corev1 .SecretTypeOpaque ,
200
239
}
201
240
241
+ if err = controllerutil .SetOwnerReference (cluster , encryptionConfigSecret , h .client .Scheme ()); err != nil {
242
+ return fmt .Errorf (
243
+ "failed to set owner reference on encryption configuration secret: %w" ,
244
+ err ,
245
+ )
246
+ }
247
+
202
248
// We only support creating encryption config in BeforeClusterCreate hook and ensure that the keys are immutable.
203
- if err := client .Create (ctx , h .config . Client , encryptionConfigSecret ); err != nil {
204
- return "" , fmt .Errorf ("failed to create encryption configuration secret: %w" , err )
249
+ if err := k8sClientUtil .Create (ctx , h .client , encryptionConfigSecret ); err != nil {
250
+ return fmt .Errorf ("failed to create encryption configuration secret: %w" , err )
205
251
}
206
- return secretName , nil
252
+ return nil
207
253
}
208
254
209
255
// We only support encryption for "secrets" and "configmaps".
0 commit comments