Skip to content

Commit 9babd10

Browse files
committed
feat: mutation handler for encryption configuration
1 parent 56f042c commit 9babd10

9 files changed

+80
-73
lines changed

api/v1alpha1/clusterconfig_types.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,7 @@ type User struct {
287287
// Currently the encryption only enabled for secrets and configmaps.
288288
type Encryption struct {
289289
// Encryption providers
290-
// +kubebuilder:validation:Enum=aescbc;secretbox
291-
// +kubebuilder:default=aescbc
290+
// +kubebuilder:default={aescbc:{}}
292291
// +kubebuilder:validation:Optional
293292
Providers *EncryptionProviders `json:"providers"`
294293
}

api/v1alpha1/crds/caren.nutanix.com_awsclusterconfigs.yaml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,9 @@ spec:
329329
Currently the encryption only enabled for secrets and configmaps.
330330
properties:
331331
providers:
332-
default: aescbc
332+
default:
333+
aescbc: {}
333334
description: Encryption providers
334-
enum:
335-
- aescbc
336-
- secretbox
337335
properties:
338336
aescbc:
339337
type: object

api/v1alpha1/crds/caren.nutanix.com_dockerclusterconfigs.yaml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,11 +246,9 @@ spec:
246246
Currently the encryption only enabled for secrets and configmaps.
247247
properties:
248248
providers:
249-
default: aescbc
249+
default:
250+
aescbc: {}
250251
description: Encryption providers
251-
enum:
252-
- aescbc
253-
- secretbox
254252
properties:
255253
aescbc:
256254
type: object

api/v1alpha1/crds/caren.nutanix.com_genericclusterconfigs.yaml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,11 +240,9 @@ spec:
240240
Currently the encryption only enabled for secrets and configmaps.
241241
properties:
242242
providers:
243-
default: aescbc
243+
default:
244+
aescbc: {}
244245
description: Encryption providers
245-
enum:
246-
- aescbc
247-
- secretbox
248246
properties:
249247
aescbc:
250248
type: object

api/v1alpha1/crds/caren.nutanix.com_nutanixclusterconfigs.yaml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -417,11 +417,9 @@ spec:
417417
Currently the encryption only enabled for secrets and configmaps.
418418
properties:
419419
providers:
420-
default: aescbc
420+
default:
421+
aescbc: {}
421422
description: Encryption providers
422-
enum:
423-
- aescbc
424-
- secretbox
425423
properties:
426424
aescbc:
427425
type: object

pkg/handlers/generic/mutation/encryption/encryptionprovider_test.go

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ package encryption
55

66
import (
77
"encoding/base64"
8-
"errors"
98
"testing"
109

1110
"github.com/stretchr/testify/assert"
@@ -17,14 +16,17 @@ import (
1716
func Test_encryptionConfigForSecretsAndConfigMaps(t *testing.T) {
1817
testcases := []struct {
1918
name string
20-
providers []carenv1.EncryptionProvider
19+
providers *carenv1.EncryptionProviders
2120
wantErr error
2221
want *apiserverv1.ResourceConfiguration
2322
}{
2423
{
25-
name: "encryption configuration using aescbc and secretbox providers",
26-
providers: []carenv1.EncryptionProvider{carenv1.AESCBC, carenv1.SecretBox},
27-
wantErr: nil,
24+
name: "encryption configuration using all providers",
25+
providers: &carenv1.EncryptionProviders{
26+
AESCBC: &carenv1.AESConfiguration{},
27+
Secretbox: &carenv1.SecretboxConfiguration{},
28+
},
29+
wantErr: nil,
2830
want: &apiserverv1.ResourceConfiguration{
2931
Resources: []string{"secrets", "configmaps"},
3032
Providers: []apiserverv1.ProviderConfiguration{
@@ -50,10 +52,26 @@ func Test_encryptionConfigForSecretsAndConfigMaps(t *testing.T) {
5052
},
5153
},
5254
{
53-
name: "unsupported encryption provider",
54-
providers: []carenv1.EncryptionProvider{carenv1.EncryptionProvider("kmsv2")},
55-
wantErr: errors.New("unknown encryption provider: kmsv2"),
56-
want: nil,
55+
name: "encryption configuration using single provider",
56+
providers: &carenv1.EncryptionProviders{
57+
AESCBC: &carenv1.AESConfiguration{},
58+
},
59+
wantErr: nil,
60+
want: &apiserverv1.ResourceConfiguration{
61+
Resources: []string{"secrets", "configmaps"},
62+
Providers: []apiserverv1.ProviderConfiguration{
63+
{
64+
AESCBC: &apiserverv1.AESConfiguration{
65+
Keys: []apiserverv1.Key{
66+
{
67+
Name: "key1",
68+
Secret: base64.StdEncoding.EncodeToString([]byte(testToken)),
69+
},
70+
},
71+
},
72+
},
73+
},
74+
},
5775
},
5876
}
5977

pkg/handlers/generic/mutation/encryption/inject.go

Lines changed: 36 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ func generateEncryptionCredentialsFile(secretName string) cabpkv1.File {
150150
}
151151

152152
func (h *encryptionPatchHandler) generateEncryptionConfiguration(
153-
providers []carenv1.EncryptionProvider,
153+
providers *carenv1.EncryptionProviders,
154154
) (*apiserverv1.EncryptionConfiguration, error) {
155155
// We only support encryption for "secrets" and "configmaps" using "aescbc" provider.
156156
resourceConfig, err := encryptionConfigForSecretsAndConfigMaps(
@@ -182,7 +182,6 @@ func (h *encryptionPatchHandler) CreateEncryptionConfigurationSecret(
182182
}
183183

184184
secretData := map[string]string{
185-
// creating a Secret with newlines at the end fails
186185
SecretKeyForEtcdEncryption: strings.TrimSpace(string(dataYaml)),
187186
}
188187
secretName := defaultEncryptionSecretName(clusterKey.Name)
@@ -201,59 +200,53 @@ func (h *encryptionPatchHandler) CreateEncryptionConfigurationSecret(
201200
}
202201

203202
// We only support creating encryption config in BeforeClusterCreate hook and ensure that the keys are immutable.
204-
// Rotation of the keys can be implemented by cloning existing secret and adding new rotation key.
205203
if err := client.Create(ctx, h.config.Client, encryptionConfigSecret); err != nil {
206-
return "", fmt.Errorf("failed to create Encryption Configuration Secret: %w", err)
204+
return "", fmt.Errorf("failed to create encryption configuration secret: %w", err)
207205
}
208206
return secretName, nil
209207
}
210208

211209
// We only support encryption for "secrets" and "configmaps".
212210
func encryptionConfigForSecretsAndConfigMaps(
213-
providers []carenv1.EncryptionProvider,
211+
providers *carenv1.EncryptionProviders,
214212
secretGenerator TokenGenerator,
215213
) (*apiserverv1.ResourceConfiguration, error) {
216214
providerConfig := apiserverv1.ProviderConfiguration{}
217-
for _, providerType := range providers {
218-
// We only support "aescbc", "secretbox" for now.
219-
// "aesgcm" is another AESConfiguration. "aesgcm" requires secret key rotation before 200k write calls.
220-
// It should not be supported until secret key's rotation is implemented.
221-
switch providerType {
222-
case carenv1.AESCBC:
223-
token, err := secretGenerator()
224-
if err != nil {
225-
return nil, fmt.Errorf(
226-
"could not create random encryption token for aescbc provider: %w",
227-
err,
228-
)
229-
}
230-
providerConfig.AESCBC = &apiserverv1.AESConfiguration{
231-
Keys: []apiserverv1.Key{
232-
{
233-
Name: "key1", // we only support one key during cluster creation.
234-
Secret: base64.StdEncoding.EncodeToString(token),
235-
},
215+
// We only support "aescbc", "secretbox" for now.
216+
// "aesgcm" is another AESConfiguration. "aesgcm" requires secret key rotation before 200k write calls.
217+
// "aesgcm" should not be supported until secret key's rotation is implemented.
218+
if providers.AESCBC != nil {
219+
token, err := secretGenerator()
220+
if err != nil {
221+
return nil, fmt.Errorf(
222+
"could not create random encryption token for aescbc provider: %w",
223+
err,
224+
)
225+
}
226+
providerConfig.AESCBC = &apiserverv1.AESConfiguration{
227+
Keys: []apiserverv1.Key{
228+
{
229+
Name: "key1", // we only support one key during cluster creation.
230+
Secret: base64.StdEncoding.EncodeToString(token),
236231
},
237-
}
238-
case carenv1.SecretBox:
239-
token, err := secretGenerator()
240-
if err != nil {
241-
return nil, fmt.Errorf(
242-
"could not create random encryption token for secretbox provider: %w",
243-
err,
244-
)
245-
}
246-
providerConfig.Secretbox = &apiserverv1.SecretboxConfiguration{
247-
Keys: []apiserverv1.Key{
248-
{
249-
Name: "key1", // we only support one key during cluster creation.
250-
Secret: base64.StdEncoding.EncodeToString(token),
251-
},
232+
},
233+
}
234+
}
235+
if providers.Secretbox != nil {
236+
token, err := secretGenerator()
237+
if err != nil {
238+
return nil, fmt.Errorf(
239+
"could not create random encryption token for secretbox provider: %w",
240+
err,
241+
)
242+
}
243+
providerConfig.Secretbox = &apiserverv1.SecretboxConfiguration{
244+
Keys: []apiserverv1.Key{
245+
{
246+
Name: "key1", // we only support one key during cluster creation.
247+
Secret: base64.StdEncoding.EncodeToString(token),
252248
},
253-
}
254-
default:
255-
// Schema validation should fail earlier upon providing name outside defined Enum
256-
return nil, fmt.Errorf("unknown encryption provider: %s", providerType)
249+
},
257250
}
258251
}
259252

pkg/handlers/generic/mutation/encryption/inject_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ var _ = Describe("Generate Encryption configuration patches", func() {
6969
capitest.VariableWithValue(
7070
clusterconfig.MetaVariableName,
7171
carenv1.Encryption{
72-
Providers: []carenv1.EncryptionProvider{
73-
carenv1.AESCBC,
74-
carenv1.SecretBox,
72+
Providers: &carenv1.EncryptionProviders{
73+
AESCBC: &carenv1.AESConfiguration{},
74+
Secretbox: &carenv1.SecretboxConfiguration{},
7575
},
7676
},
7777
VariableName,

pkg/handlers/generic/mutation/handlers.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/auditpolicy"
1212
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/containerdapplypatchesandrestart"
1313
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/containerdmetrics"
14+
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/encryption"
1415
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/etcd"
1516
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/extraapiservercertsans"
1617
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/httpproxy"
@@ -33,6 +34,10 @@ func MetaMutators(mgr manager.Manager) []mutation.MetaMutator {
3334
calico.NewPatch(),
3435
users.NewPatch(),
3536
containerdmetrics.NewPatch(),
37+
encryption.NewPatch(&encryption.Config{
38+
Client: mgr.GetClient(),
39+
AESSecretKeyGenerator: encryption.RandomTokenGenerator,
40+
}),
3641

3742
// Some patches may have changed containerd configuration.
3843
// We write the configuration changes to disk, and must run a command

0 commit comments

Comments
 (0)