diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go b/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go index 15c04898f98..9adb5dd86fb 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go +++ b/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go @@ -48,6 +48,7 @@ import ( "k8s.io/apiserver/pkg/storage/value/encrypt/identity" "k8s.io/apiserver/pkg/storage/value/encrypt/secretbox" utilfeature "k8s.io/apiserver/pkg/util/feature" + kmsservice "k8s.io/kms/service" ) const ( @@ -85,7 +86,7 @@ type kmsPluginProbe struct { type kmsv2PluginProbe struct { name string ttl time.Duration - service envelopekmsv2.Service + service kmsservice.Service lastResponse *kmsPluginHealthzResponse l *sync.Mutex } @@ -284,7 +285,7 @@ func (h *kmsv2PluginProbe) check(ctx context.Context) error { } // isKMSv2ProviderHealthy checks if the KMSv2-Plugin is healthy. -func isKMSv2ProviderHealthy(name string, response *envelopekmsv2.StatusResponse) error { +func isKMSv2ProviderHealthy(name string, response *kmsservice.StatusResponse) error { var errs []error if response.Healthz != "ok" { errs = append(errs, fmt.Errorf("got unexpected healthz status: %s", response.Healthz)) diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config_test.go b/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config_test.go index 767bfc6c110..3e82a00f3ff 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config_test.go +++ b/staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config_test.go @@ -32,9 +32,9 @@ import ( "k8s.io/apiserver/pkg/features" "k8s.io/apiserver/pkg/storage/value" "k8s.io/apiserver/pkg/storage/value/encrypt/envelope" - envelopekmsv2 "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2" utilfeature "k8s.io/apiserver/pkg/util/feature" featuregatetesting "k8s.io/component-base/featuregate/testing" + kmsservice "k8s.io/kms/service" ) const ( @@ -68,28 +68,28 @@ type testKMSv2EnvelopeService struct { err error } -func (t *testKMSv2EnvelopeService) Decrypt(ctx context.Context, uid string, req *envelopekmsv2.DecryptRequest) ([]byte, error) { +func (t *testKMSv2EnvelopeService) Decrypt(ctx context.Context, uid string, req *kmsservice.DecryptRequest) ([]byte, error) { if t.err != nil { return nil, t.err } return base64.StdEncoding.DecodeString(string(req.Ciphertext)) } -func (t *testKMSv2EnvelopeService) Encrypt(ctx context.Context, uid string, data []byte) (*envelopekmsv2.EncryptResponse, error) { +func (t *testKMSv2EnvelopeService) Encrypt(ctx context.Context, uid string, data []byte) (*kmsservice.EncryptResponse, error) { if t.err != nil { return nil, t.err } - return &envelopekmsv2.EncryptResponse{ + return &kmsservice.EncryptResponse{ Ciphertext: []byte(base64.StdEncoding.EncodeToString(data)), KeyID: "1", }, nil } -func (t *testKMSv2EnvelopeService) Status(ctx context.Context) (*envelopekmsv2.StatusResponse, error) { +func (t *testKMSv2EnvelopeService) Status(ctx context.Context) (*kmsservice.StatusResponse, error) { if t.err != nil { return nil, t.err } - return &envelopekmsv2.StatusResponse{Healthz: "ok", KeyID: "1", Version: "v2alpha1"}, nil + return &kmsservice.StatusResponse{Healthz: "ok", KeyID: "1", Version: "v2alpha1"}, nil } // The factory method to create mock envelope service. @@ -103,12 +103,12 @@ func newMockErrorEnvelopeService(endpoint string, timeout time.Duration) (envelo } // The factory method to create mock envelope kmsv2 service. -func newMockEnvelopeKMSv2Service(ctx context.Context, endpoint string, timeout time.Duration) (envelopekmsv2.Service, error) { +func newMockEnvelopeKMSv2Service(ctx context.Context, endpoint string, timeout time.Duration) (kmsservice.Service, error) { return &testKMSv2EnvelopeService{nil}, nil } // The factory method to create mock envelope kmsv2 service which always returns error. -func newMockErrorEnvelopeKMSv2Service(endpoint string, timeout time.Duration) (envelopekmsv2.Service, error) { +func newMockErrorEnvelopeKMSv2Service(endpoint string, timeout time.Duration) (kmsservice.Service, error) { return &testKMSv2EnvelopeService{errors.New("test")}, nil } @@ -773,23 +773,23 @@ func getTransformerFromEncryptionConfig(t *testing.T, encryptionConfigPath strin func TestIsKMSv2ProviderHealthyError(t *testing.T) { testCases := []struct { desc string - statusResponse *envelopekmsv2.StatusResponse + statusResponse *kmsservice.StatusResponse }{ { desc: "healthz status is not ok", - statusResponse: &envelopekmsv2.StatusResponse{ + statusResponse: &kmsservice.StatusResponse{ Healthz: "unhealthy", }, }, { desc: "version is not v2alpha1", - statusResponse: &envelopekmsv2.StatusResponse{ + statusResponse: &kmsservice.StatusResponse{ Version: "v1beta1", }, }, { desc: "missing keyID", - statusResponse: &envelopekmsv2.StatusResponse{ + statusResponse: &kmsservice.StatusResponse{ Healthz: "ok", Version: "v2alpha1", }, 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 726e3053e3f..927e86fe167 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 @@ -35,6 +35,7 @@ import ( kmstypes "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1" "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics" "k8s.io/klog/v2" + kmsservice "k8s.io/kms/service" "k8s.io/utils/lru" ) @@ -49,18 +50,8 @@ const ( encryptedDEKMaxSize = 1 * 1024 // 1 kB ) -// Service allows encrypting and decrypting data using an external Key Management Service. -type Service interface { - // Decrypt a given bytearray to obtain the original data as bytes. - Decrypt(ctx context.Context, uid string, req *DecryptRequest) ([]byte, error) - // Encrypt bytes to a ciphertext. - Encrypt(ctx context.Context, uid string, data []byte) (*EncryptResponse, error) - // Status returns the status of the KMS. - Status(ctx context.Context) (*StatusResponse, error) -} - type envelopeTransformer struct { - envelopeService Service + envelopeService kmsservice.Service // transformers is a thread-safe LRU cache which caches decrypted DEKs indexed by their encrypted form. transformers *lru.Cache @@ -72,32 +63,11 @@ type envelopeTransformer struct { cacheEnabled bool } -// EncryptResponse is the response from the Envelope service when encrypting data. -type EncryptResponse struct { - Ciphertext []byte - KeyID string - Annotations map[string][]byte -} - -// DecryptRequest is the request to the Envelope service when decrypting data. -type DecryptRequest struct { - Ciphertext []byte - KeyID string - Annotations map[string][]byte -} - -// StatusResponse is the response from the Envelope service when getting the status of the service. -type StatusResponse struct { - Version string - Healthz string - KeyID string -} - // NewEnvelopeTransformer returns a transformer which implements a KEK-DEK based envelope encryption scheme. // It uses envelopeService to encrypt and decrypt DEKs. Respective DEKs (in encrypted form) are prepended to // the data items they encrypt. A cache (of size cacheSize) is maintained to store the most recently // used decrypted DEKs in memory. -func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransformerFunc func(cipher.Block) value.Transformer) value.Transformer { +func NewEnvelopeTransformer(envelopeService kmsservice.Service, cacheSize int, baseTransformerFunc func(cipher.Block) value.Transformer) value.Transformer { var cache *lru.Cache if cacheSize > 0 { @@ -133,7 +103,7 @@ func (t *envelopeTransformer) TransformFromStorage(ctx context.Context, data []b } uid := string(uuid.NewUUID()) klog.V(6).InfoS("Decrypting content using envelope service", "uid", uid, "key", string(dataCtx.AuthenticatedData())) - key, err := t.envelopeService.Decrypt(ctx, uid, &DecryptRequest{ + key, err := t.envelopeService.Decrypt(ctx, uid, &kmsservice.DecryptRequest{ Ciphertext: encryptedObject.EncryptedDEK, KeyID: encryptedObject.KeyID, Annotations: encryptedObject.Annotations, 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 db876c50005..c7ec176c630 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 @@ -30,6 +30,7 @@ import ( "k8s.io/apiserver/pkg/storage/value" aestransformer "k8s.io/apiserver/pkg/storage/value/encrypt/aes" kmstypes "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1" + kmsservice "k8s.io/kms/service" ) const ( @@ -46,7 +47,7 @@ type testEnvelopeService struct { keyVersion string } -func (t *testEnvelopeService) Decrypt(ctx context.Context, uid string, req *DecryptRequest) ([]byte, error) { +func (t *testEnvelopeService) Decrypt(ctx context.Context, uid string, req *kmsservice.DecryptRequest) ([]byte, error) { if t.disabled { return nil, fmt.Errorf("Envelope service was disabled") } @@ -59,7 +60,7 @@ func (t *testEnvelopeService) Decrypt(ctx context.Context, uid string, req *Decr return base64.StdEncoding.DecodeString(string(req.Ciphertext)) } -func (t *testEnvelopeService) Encrypt(ctx context.Context, uid string, data []byte) (*EncryptResponse, error) { +func (t *testEnvelopeService) Encrypt(ctx context.Context, uid string, data []byte) (*kmsservice.EncryptResponse, error) { if t.disabled { return nil, fmt.Errorf("Envelope service was disabled") } @@ -74,14 +75,14 @@ func (t *testEnvelopeService) Encrypt(ctx context.Context, uid string, data []by } else { annotations["local-kek.kms.kubernetes.io"] = []byte("encrypted-local-kek") } - return &EncryptResponse{Ciphertext: []byte(base64.StdEncoding.EncodeToString(data)), KeyID: t.keyVersion, Annotations: annotations}, nil + return &kmsservice.EncryptResponse{Ciphertext: []byte(base64.StdEncoding.EncodeToString(data)), KeyID: t.keyVersion, Annotations: annotations}, nil } -func (t *testEnvelopeService) Status(ctx context.Context) (*StatusResponse, error) { +func (t *testEnvelopeService) Status(ctx context.Context) (*kmsservice.StatusResponse, error) { if t.disabled { return nil, fmt.Errorf("Envelope service was disabled") } - return &StatusResponse{KeyID: t.keyVersion}, nil + return &kmsservice.StatusResponse{KeyID: t.keyVersion}, nil } func (t *testEnvelopeService) SetDisabledStatus(status bool) { diff --git a/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go b/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go index 692aeef53a9..cd22fa8d932 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service.go @@ -30,6 +30,7 @@ import ( "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util" "k8s.io/klog/v2" kmsapi "k8s.io/kms/apis/v2alpha1" + kmsservice "k8s.io/kms/service" ) const ( @@ -45,7 +46,7 @@ type gRPCService struct { } // NewGRPCService returns an envelope.Service which use gRPC to communicate the remote KMS provider. -func NewGRPCService(ctx context.Context, endpoint string, callTimeout time.Duration) (Service, error) { +func NewGRPCService(ctx context.Context, endpoint string, callTimeout time.Duration) (kmsservice.Service, error) { klog.V(4).Infof("Configure KMS provider with endpoint: %s", endpoint) addr, err := util.ParseEndpoint(endpoint) @@ -88,7 +89,7 @@ func NewGRPCService(ctx context.Context, endpoint string, callTimeout time.Durat } // Decrypt a given data string to obtain the original byte data. -func (g *gRPCService) Decrypt(ctx context.Context, uid string, req *DecryptRequest) ([]byte, error) { +func (g *gRPCService) Decrypt(ctx context.Context, uid string, req *kmsservice.DecryptRequest) ([]byte, error) { ctx, cancel := context.WithTimeout(ctx, g.callTimeout) defer cancel() @@ -106,7 +107,7 @@ func (g *gRPCService) Decrypt(ctx context.Context, uid string, req *DecryptReque } // Encrypt bytes to a string ciphertext. -func (g *gRPCService) Encrypt(ctx context.Context, uid string, plaintext []byte) (*EncryptResponse, error) { +func (g *gRPCService) Encrypt(ctx context.Context, uid string, plaintext []byte) (*kmsservice.EncryptResponse, error) { ctx, cancel := context.WithTimeout(ctx, g.callTimeout) defer cancel() @@ -118,7 +119,7 @@ func (g *gRPCService) Encrypt(ctx context.Context, uid string, plaintext []byte) if err != nil { return nil, err } - return &EncryptResponse{ + return &kmsservice.EncryptResponse{ Ciphertext: response.Ciphertext, KeyID: response.KeyId, Annotations: response.Annotations, @@ -126,7 +127,7 @@ func (g *gRPCService) Encrypt(ctx context.Context, uid string, plaintext []byte) } // Status returns the status of the KMSv2 provider. -func (g *gRPCService) Status(ctx context.Context) (*StatusResponse, error) { +func (g *gRPCService) Status(ctx context.Context) (*kmsservice.StatusResponse, error) { ctx, cancel := context.WithTimeout(ctx, g.callTimeout) defer cancel() @@ -135,5 +136,5 @@ func (g *gRPCService) Status(ctx context.Context) (*StatusResponse, error) { if err != nil { return nil, err } - return &StatusResponse{Version: response.Version, Healthz: response.Healthz, KeyID: response.KeyId}, nil + return &kmsservice.StatusResponse{Version: response.Version, Healthz: response.Healthz, KeyID: response.KeyId}, nil } diff --git a/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service_unix_test.go b/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service_unix_test.go index 41c3ca9670a..7f2ac4f94d8 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service_unix_test.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/grpc_service_unix_test.go @@ -28,6 +28,7 @@ import ( mock "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/testing/v2alpha1" "k8s.io/apimachinery/pkg/util/uuid" + kmsservice "k8s.io/kms/service" ) type testSocket struct { @@ -120,7 +121,7 @@ func TestTimeouts(t *testing.T) { t.Run(tt.desc, func(t *testing.T) { t.Parallel() var ( - service Service + service kmsservice.Service err error data = []byte("test data") uid = string(uuid.NewUUID()) @@ -293,7 +294,7 @@ func TestGRPCService(t *testing.T) { keyID := "1" // Call service to decrypt data. - result, err := service.Decrypt(ctx, uid, &DecryptRequest{Ciphertext: resp.Ciphertext, KeyID: keyID}) + result, err := service.Decrypt(ctx, uid, &kmsservice.DecryptRequest{Ciphertext: resp.Ciphertext, KeyID: keyID}) if err != nil { t.Fatalf("failed when execute decrypt, error: %v", err) } @@ -342,7 +343,7 @@ func TestGRPCServiceConcurrentAccess(t *testing.T) { keyID := "1" // Call service to decrypt data. - result, err := service.Decrypt(ctx, uid, &DecryptRequest{Ciphertext: resp.Ciphertext, KeyID: keyID}) + result, err := service.Decrypt(ctx, uid, &kmsservice.DecryptRequest{Ciphertext: resp.Ciphertext, KeyID: keyID}) if err != nil { t.Errorf("failed when execute decrypt, error: %v", err) } @@ -356,7 +357,7 @@ func TestGRPCServiceConcurrentAccess(t *testing.T) { wg.Wait() } -func destroyService(service Service) { +func destroyService(service kmsservice.Service) { if service != nil { s := service.(*gRPCService) s.connection.Close() diff --git a/staging/src/k8s.io/kms/service/interface.go b/staging/src/k8s.io/kms/service/interface.go index c03c1ade27e..fad71fa0a3c 100644 --- a/staging/src/k8s.io/kms/service/interface.go +++ b/staging/src/k8s.io/kms/service/interface.go @@ -18,10 +18,6 @@ package service import "context" -/* -Copied from: k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2 -*/ - // Service allows encrypting and decrypting data using an external Key Management Service. type Service interface { // Decrypt a given bytearray to obtain the original data as bytes. diff --git a/test/integration/controlplane/transformation/kmsv2_transformation_test.go b/test/integration/controlplane/transformation/kmsv2_transformation_test.go index 427f948c212..7ef910903ec 100644 --- a/test/integration/controlplane/transformation/kmsv2_transformation_test.go +++ b/test/integration/controlplane/transformation/kmsv2_transformation_test.go @@ -40,13 +40,13 @@ import ( "k8s.io/apiserver/pkg/server/options/encryptionconfig" "k8s.io/apiserver/pkg/storage/value" aestransformer "k8s.io/apiserver/pkg/storage/value/encrypt/aes" - "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2" kmstypes "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1" kmsv2mock "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/testing/v2alpha1" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/dynamic" featuregatetesting "k8s.io/component-base/featuregate/testing" kmsv2api "k8s.io/kms/apis/v2alpha1" + kmsv2svc "k8s.io/kms/service" "k8s.io/kubernetes/test/integration/etcd" ) @@ -300,7 +300,7 @@ func TestKMSv2SingleService(t *testing.T) { var kmsv2Calls int origEnvelopeKMSv2ServiceFactory := encryptionconfig.EnvelopeKMSv2ServiceFactory - encryptionconfig.EnvelopeKMSv2ServiceFactory = func(ctx context.Context, endpoint string, callTimeout time.Duration) (kmsv2.Service, error) { + encryptionconfig.EnvelopeKMSv2ServiceFactory = func(ctx context.Context, endpoint string, callTimeout time.Duration) (kmsv2svc.Service, error) { kmsv2Calls++ return origEnvelopeKMSv2ServiceFactory(ctx, endpoint, callTimeout) } diff --git a/vendor/modules.txt b/vendor/modules.txt index b8f88661475..6829bd84079 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -2098,6 +2098,7 @@ k8s.io/klog/v2/test ## explicit; go 1.19 k8s.io/kms/apis/v1beta1 k8s.io/kms/apis/v2alpha1 +k8s.io/kms/service # k8s.io/kube-aggregator v0.0.0 => ./staging/src/k8s.io/kube-aggregator ## explicit; go 1.19 k8s.io/kube-aggregator/pkg/apis/apiregistration