mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Merge pull request #114922 from ibihim/kmsv2-interface-move
[KMSv2] apiserver/kmsv2: mv Service interface into kmsv2
This commit is contained in:
commit
f7b02260f6
@ -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))
|
||||
|
@ -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",
|
||||
},
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
}
|
||||
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user