diff --git a/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go b/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go index 43ba22d65e0..e372e62de7c 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope.go @@ -265,6 +265,8 @@ func (t *envelopeTransformer) doDecode(originalData []byte) (*kmstypes.Encrypted return o, nil } +// GenerateTransformer generates a new transformer and encrypts the DEK using the envelope service. +// It returns the transformer, the encrypted DEK, cache key and error. func GenerateTransformer(ctx context.Context, uid string, envelopeService kmsservice.Service) (value.Transformer, *kmsservice.EncryptResponse, []byte, error) { transformer, newKey, err := aestransformer.NewGCMTransformerWithUniqueKeyUnsafe() if err != nil { diff --git a/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope_test.go b/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope_test.go index 0b16f8c133a..573cee6b58b 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope_test.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/envelope_test.go @@ -990,6 +990,86 @@ func TestGenerateCacheKey(t *testing.T) { } } +func TestGenerateTransformer(t *testing.T) { + t.Parallel() + testCases := []struct { + name string + envelopeService func() kmsservice.Service + expectedErr string + }{ + { + name: "encrypt call fails", + envelopeService: func() kmsservice.Service { + envelopeService := newTestEnvelopeService() + envelopeService.SetDisabledStatus(true) + return envelopeService + }, + expectedErr: "Envelope service was disabled", + }, + { + name: "invalid key ID", + envelopeService: func() kmsservice.Service { + envelopeService := newTestEnvelopeService() + envelopeService.keyVersion = "" + return envelopeService + }, + expectedErr: "failed to validate key id: keyID is empty", + }, + { + name: "invalid encrypted DEK", + envelopeService: func() kmsservice.Service { + envelopeService := newTestEnvelopeService() + envelopeService.SetCiphertext([]byte{}) + return envelopeService + }, + expectedErr: "failed to validate encrypted DEK: encrypted DEK is empty", + }, + { + name: "invalid annotations", + envelopeService: func() kmsservice.Service { + envelopeService := newTestEnvelopeService() + envelopeService.SetAnnotations(map[string][]byte{"invalid": {}}) + return envelopeService + }, + expectedErr: "failed to validate annotations: annotations: Invalid value: \"invalid\": should be a domain with at least two segments separated by dots", + }, + { + name: "success", + envelopeService: func() kmsservice.Service { + return newTestEnvelopeService() + }, + expectedErr: "", + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + transformer, encryptResp, cacheKey, err := GenerateTransformer(testContext(t), "panda", tc.envelopeService()) + if tc.expectedErr == "" { + if err != nil { + t.Errorf("expected no error, got %q", errString(err)) + } + if transformer == nil { + t.Error("expected transformer, got nil") + } + if encryptResp == nil { + t.Error("expected encrypt response, got nil") + } + if cacheKey == nil { + t.Error("expected cache key, got nil") + } + } else { + if err == nil || !strings.Contains(err.Error(), tc.expectedErr) { + t.Errorf("expected error %q, got %q", tc.expectedErr, errString(err)) + } + } + }) + } +} + func errString(err error) string { if err == nil { return ""