Upgrade k8s package verison (#5358)

* upgrade k8s package version

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>

* Script upgrade and code formatting.

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>
This commit is contained in:
hongzhouzi
2022-11-15 14:56:38 +08:00
committed by GitHub
parent 5f91c1663a
commit 44167aa47a
3106 changed files with 321340 additions and 172080 deletions

View File

@@ -19,6 +19,7 @@ package aes
import (
"bytes"
"context"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
@@ -52,7 +53,7 @@ func NewGCMTransformer(block cipher.Block) value.Transformer {
return &gcm{block: block}
}
func (t *gcm) TransformFromStorage(data []byte, context value.Context) ([]byte, bool, error) {
func (t *gcm) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) {
aead, err := cipher.NewGCM(t.block)
if err != nil {
return nil, false, err
@@ -61,11 +62,11 @@ func (t *gcm) TransformFromStorage(data []byte, context value.Context) ([]byte,
if len(data) < nonceSize {
return nil, false, fmt.Errorf("the stored data was shorter than the required size")
}
result, err := aead.Open(nil, data[:nonceSize], data[nonceSize:], context.AuthenticatedData())
result, err := aead.Open(nil, data[:nonceSize], data[nonceSize:], dataCtx.AuthenticatedData())
return result, false, err
}
func (t *gcm) TransformToStorage(data []byte, context value.Context) ([]byte, error) {
func (t *gcm) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) {
aead, err := cipher.NewGCM(t.block)
if err != nil {
return nil, err
@@ -79,7 +80,7 @@ func (t *gcm) TransformToStorage(data []byte, context value.Context) ([]byte, er
if n != nonceSize {
return nil, fmt.Errorf("unable to read sufficient random bytes")
}
cipherText := aead.Seal(result[nonceSize:nonceSize], result[:nonceSize], data, context.AuthenticatedData())
cipherText := aead.Seal(result[nonceSize:nonceSize], result[:nonceSize], data, dataCtx.AuthenticatedData())
return result[:nonceSize+len(cipherText)], nil
}
@@ -95,12 +96,12 @@ func NewCBCTransformer(block cipher.Block) value.Transformer {
}
var (
errInvalidBlockSize = fmt.Errorf("the stored data is not a multiple of the block size")
ErrInvalidBlockSize = fmt.Errorf("the stored data is not a multiple of the block size")
errInvalidPKCS7Data = errors.New("invalid PKCS7 data (empty or not padded)")
errInvalidPKCS7Padding = errors.New("invalid padding on input")
)
func (t *cbc) TransformFromStorage(data []byte, context value.Context) ([]byte, bool, error) {
func (t *cbc) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) {
blockSize := aes.BlockSize
if len(data) < blockSize {
return nil, false, fmt.Errorf("the stored data was shorter than the required size")
@@ -109,7 +110,7 @@ func (t *cbc) TransformFromStorage(data []byte, context value.Context) ([]byte,
data = data[blockSize:]
if len(data)%blockSize != 0 {
return nil, false, errInvalidBlockSize
return nil, false, ErrInvalidBlockSize
}
result := make([]byte, len(data))
@@ -133,7 +134,7 @@ func (t *cbc) TransformFromStorage(data []byte, context value.Context) ([]byte,
return result[:size], false, nil
}
func (t *cbc) TransformToStorage(data []byte, context value.Context) ([]byte, error) {
func (t *cbc) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) {
blockSize := aes.BlockSize
paddingSize := blockSize - (len(data) % blockSize)
result := make([]byte, blockSize+len(data)+paddingSize)

View File

@@ -18,6 +18,7 @@ limitations under the License.
package envelope
import (
"context"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
@@ -26,14 +27,15 @@ import (
"time"
"k8s.io/apiserver/pkg/storage/value"
"k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics"
"k8s.io/utils/lru"
lru "github.com/hashicorp/golang-lru"
"golang.org/x/crypto/cryptobyte"
)
func init() {
value.RegisterMetrics()
registerMetrics()
metrics.RegisterMetrics()
}
// Service allows encrypting and decrypting data using an external Key Management Service.
@@ -64,14 +66,10 @@ type envelopeTransformer struct {
func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransformerFunc func(cipher.Block) value.Transformer) (value.Transformer, error) {
var (
cache *lru.Cache
err error
)
if cacheSize > 0 {
cache, err = lru.New(cacheSize)
if err != nil {
return nil, err
}
cache = lru.New(cacheSize)
}
return &envelopeTransformer{
envelopeService: envelopeService,
@@ -83,8 +81,8 @@ func NewEnvelopeTransformer(envelopeService Service, cacheSize int, baseTransfor
}
// TransformFromStorage decrypts data encrypted by this transformer using envelope encryption.
func (t *envelopeTransformer) TransformFromStorage(data []byte, context value.Context) ([]byte, bool, error) {
recordArrival(fromStorageLabel, time.Now())
func (t *envelopeTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) {
metrics.RecordArrival(metrics.FromStorageLabel, time.Now())
// Read the 16 bit length-of-DEK encoded at the start of the encrypted DEK. 16 bits can
// represent a maximum key length of 65536 bytes. We are using a 256 bit key, whose
@@ -117,12 +115,12 @@ func (t *envelopeTransformer) TransformFromStorage(data []byte, context value.Co
}
}
return transformer.TransformFromStorage(encData, context)
return transformer.TransformFromStorage(ctx, encData, dataCtx)
}
// TransformToStorage encrypts data to be written to disk using envelope encryption.
func (t *envelopeTransformer) TransformToStorage(data []byte, context value.Context) ([]byte, error) {
recordArrival(toStorageLabel, time.Now())
func (t *envelopeTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) {
metrics.RecordArrival(metrics.ToStorageLabel, time.Now())
newKey, err := generateKey(32)
if err != nil {
return nil, err
@@ -141,7 +139,7 @@ func (t *envelopeTransformer) TransformToStorage(data []byte, context value.Cont
return nil, err
}
result, err := transformer.TransformToStorage(data, context)
result, err := transformer.TransformToStorage(ctx, data, dataCtx)
if err != nil {
return nil, err
}
@@ -168,7 +166,7 @@ func (t *envelopeTransformer) addTransformer(encKey []byte, key []byte) (value.T
// cannot hash []uint8.
if t.cacheEnabled {
t.transformers.Add(base64.StdEncoding.EncodeToString(encKey), transformer)
dekCacheFillPercent.Set(float64(t.transformers.Len()) / float64(t.cacheSize))
metrics.RecordDekCacheFillPercent(float64(t.transformers.Len()) / float64(t.cacheSize))
}
return transformer, nil
}

View File

@@ -21,22 +21,21 @@ import (
"context"
"fmt"
"net"
"net/url"
"strings"
"sync"
"time"
"k8s.io/klog/v2"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util"
kmsapi "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v1beta1"
)
const (
// Now only supported unix domain socket.
// unixProtocol is the only supported protocol for remote KMS provider.
unixProtocol = "unix"
// Current version for the protocol interface definition.
kmsapiVersion = "v1beta1"
@@ -56,7 +55,7 @@ type gRPCService struct {
func NewGRPCService(endpoint string, callTimeout time.Duration) (Service, error) {
klog.V(4).Infof("Configure KMS provider with endpoint: %s", endpoint)
addr, err := parseEndpoint(endpoint)
addr, err := util.ParseEndpoint(endpoint)
if err != nil {
return nil, err
}
@@ -64,7 +63,7 @@ func NewGRPCService(endpoint string, callTimeout time.Duration) (Service, error)
s := &gRPCService{callTimeout: callTimeout}
s.connection, err = grpc.Dial(
addr,
grpc.WithInsecure(),
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithUnaryInterceptor(s.interceptor),
grpc.WithDefaultCallOptions(grpc.WaitForReady(true)),
grpc.WithContextDialer(
@@ -88,32 +87,6 @@ func NewGRPCService(endpoint string, callTimeout time.Duration) (Service, error)
return s, nil
}
// Parse the endpoint to extract schema, host or path.
func parseEndpoint(endpoint string) (string, error) {
if len(endpoint) == 0 {
return "", fmt.Errorf("remote KMS provider can't use empty string as endpoint")
}
u, err := url.Parse(endpoint)
if err != nil {
return "", fmt.Errorf("invalid endpoint %q for remote KMS provider, error: %v", endpoint, err)
}
if u.Scheme != unixProtocol {
return "", fmt.Errorf("unsupported scheme %q for remote KMS provider", u.Scheme)
}
// Linux abstract namespace socket - no physical file required
// Warning: Linux Abstract sockets have not concept of ACL (unlike traditional file based sockets).
// However, Linux Abstract sockets are subject to Linux networking namespace, so will only be accessible to
// containers within the same pod (unless host networking is used).
if strings.HasPrefix(u.Path, "/@") {
return strings.TrimPrefix(u.Path, "/"), nil
}
return u.Path, nil
}
func (g *gRPCService) checkAPIVersion(ctx context.Context) error {
g.mux.Lock()
defer g.mux.Unlock()

View File

@@ -0,0 +1,246 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package kmsv2 transforms values for storage at rest using a Envelope v2 provider
package kmsv2
import (
"context"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"fmt"
"time"
"github.com/gogo/protobuf/proto"
"k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/apiserver/pkg/storage/value"
kmstypes "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/kmsv2/v2alpha1"
"k8s.io/apiserver/pkg/storage/value/encrypt/envelope/metrics"
"k8s.io/utils/lru"
)
const (
// KMSAPIVersion is the version of the KMS API.
KMSAPIVersion = "v2alpha1"
)
// 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
// transformers is a thread-safe LRU cache which caches decrypted DEKs indexed by their encrypted form.
transformers *lru.Cache
// baseTransformerFunc creates a new transformer for encrypting the data with the DEK.
baseTransformerFunc func(cipher.Block) value.Transformer
cacheSize int
cacheEnabled bool
pluginName string
}
// 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, error) {
var cache *lru.Cache
if cacheSize > 0 {
// TODO(aramase): Switch to using expiring cache: kubernetes/kubernetes/staging/src/k8s.io/apimachinery/pkg/util/cache/expiring.go.
// It handles scans a lot better, doesn't have to be right sized, and don't have a global lock on reads.
cache = lru.New(cacheSize)
}
return &envelopeTransformer{
envelopeService: envelopeService,
transformers: cache,
baseTransformerFunc: baseTransformerFunc,
cacheEnabled: cacheSize > 0,
cacheSize: cacheSize,
}, nil
}
// TransformFromStorage decrypts data encrypted by this transformer using envelope encryption.
func (t *envelopeTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) {
metrics.RecordArrival(metrics.FromStorageLabel, time.Now())
// Deserialize the EncryptedObject from the data.
encryptedObject, err := t.doDecode(data)
if err != nil {
return nil, false, err
}
// Look up the decrypted DEK from cache or Envelope.
transformer := t.getTransformer(encryptedObject.EncryptedDEK)
if transformer == nil {
if t.cacheEnabled {
value.RecordCacheMiss()
}
uid := string(uuid.NewUUID())
key, err := t.envelopeService.Decrypt(ctx, uid, &DecryptRequest{
Ciphertext: encryptedObject.EncryptedDEK,
KeyID: encryptedObject.KeyID,
Annotations: encryptedObject.Annotations,
})
if err != nil {
return nil, false, fmt.Errorf("failed to decrypt DEK, error: %w", err)
}
transformer, err = t.addTransformer(encryptedObject.EncryptedDEK, key)
if err != nil {
return nil, false, err
}
}
return transformer.TransformFromStorage(ctx, encryptedObject.EncryptedData, dataCtx)
}
// TransformToStorage encrypts data to be written to disk using envelope encryption.
func (t *envelopeTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) {
metrics.RecordArrival(metrics.ToStorageLabel, time.Now())
newKey, err := generateKey(32)
if err != nil {
return nil, err
}
uid := string(uuid.NewUUID())
resp, err := t.envelopeService.Encrypt(ctx, uid, newKey)
if err != nil {
return nil, fmt.Errorf("failed to encrypt DEK, error: %w", err)
}
transformer, err := t.addTransformer(resp.Ciphertext, newKey)
if err != nil {
return nil, err
}
result, err := transformer.TransformToStorage(ctx, data, dataCtx)
if err != nil {
return nil, err
}
encObject := &kmstypes.EncryptedObject{
KeyID: resp.KeyID,
EncryptedDEK: resp.Ciphertext,
EncryptedData: result,
Annotations: resp.Annotations,
}
// Serialize the EncryptedObject to a byte array.
return t.doEncode(encObject)
}
// addTransformer inserts a new transformer to the Envelope cache of DEKs for future reads.
func (t *envelopeTransformer) addTransformer(encKey []byte, key []byte) (value.Transformer, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
transformer := t.baseTransformerFunc(block)
// Use base64 of encKey as the key into the cache because hashicorp/golang-lru
// cannot hash []uint8.
if t.cacheEnabled {
t.transformers.Add(base64.StdEncoding.EncodeToString(encKey), transformer)
metrics.RecordDekCacheFillPercent(float64(t.transformers.Len()) / float64(t.cacheSize))
}
return transformer, nil
}
// getTransformer fetches the transformer corresponding to encKey from cache, if it exists.
func (t *envelopeTransformer) getTransformer(encKey []byte) value.Transformer {
if !t.cacheEnabled {
return nil
}
_transformer, found := t.transformers.Get(base64.StdEncoding.EncodeToString(encKey))
if found {
return _transformer.(value.Transformer)
}
return nil
}
// doEncode encodes the EncryptedObject to a byte array.
func (t *envelopeTransformer) doEncode(request *kmstypes.EncryptedObject) ([]byte, error) {
return proto.Marshal(request)
}
// doDecode decodes the byte array to an EncryptedObject.
func (t *envelopeTransformer) doDecode(originalData []byte) (*kmstypes.EncryptedObject, error) {
o := &kmstypes.EncryptedObject{}
if err := proto.Unmarshal(originalData, o); err != nil {
return nil, err
}
// validate the EncryptedObject
if o.EncryptedData == nil {
return nil, fmt.Errorf("encrypted data is nil after unmarshal")
}
if o.KeyID == "" {
return nil, fmt.Errorf("keyID is empty after unmarshal")
}
if o.EncryptedDEK == nil {
return nil, fmt.Errorf("encrypted dek is nil after unmarshal")
}
return o, nil
}
// generateKey generates a random key using system randomness.
func generateKey(length int) (key []byte, err error) {
defer func(start time.Time) {
value.RecordDataKeyGeneration(start, err)
}(time.Now())
key = make([]byte, length)
if _, err = rand.Read(key); err != nil {
return nil, err
}
return key, nil
}

View File

@@ -0,0 +1,130 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package kmsv2 transforms values for storage at rest using a Envelope provider
package kmsv2
import (
"context"
"fmt"
"net"
"time"
"k8s.io/klog/v2"
"google.golang.org/grpc"
"k8s.io/apiserver/pkg/storage/value/encrypt/envelope/util"
kmsapi "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v2alpha1"
)
const (
// unixProtocol is the only supported protocol for remote KMS provider.
unixProtocol = "unix"
)
// The gRPC implementation for envelope.Service.
type gRPCService struct {
kmsClient kmsapi.KeyManagementServiceClient
connection *grpc.ClientConn
callTimeout time.Duration
}
// NewGRPCService returns an envelope.Service which use gRPC to communicate the remote KMS provider.
func NewGRPCService(endpoint string, callTimeout time.Duration) (Service, error) {
klog.V(4).Infof("Configure KMS provider with endpoint: %s", endpoint)
addr, err := util.ParseEndpoint(endpoint)
if err != nil {
return nil, err
}
s := &gRPCService{callTimeout: callTimeout}
s.connection, err = grpc.Dial(
addr,
grpc.WithInsecure(),
grpc.WithDefaultCallOptions(grpc.WaitForReady(true)),
grpc.WithContextDialer(
func(context.Context, string) (net.Conn, error) {
// Ignoring addr and timeout arguments:
// addr - comes from the closure
c, err := net.DialUnix(unixProtocol, nil, &net.UnixAddr{Name: addr})
if err != nil {
klog.Errorf("failed to create connection to unix socket: %s, error: %v", addr, err)
} else {
klog.V(4).Infof("Successfully dialed Unix socket %v", addr)
}
return c, err
}))
if err != nil {
return nil, fmt.Errorf("failed to create connection to %s, error: %v", endpoint, err)
}
s.kmsClient = kmsapi.NewKeyManagementServiceClient(s.connection)
return s, nil
}
// Decrypt a given data string to obtain the original byte data.
func (g *gRPCService) Decrypt(ctx context.Context, uid string, req *DecryptRequest) ([]byte, error) {
ctx, cancel := context.WithTimeout(ctx, g.callTimeout)
defer cancel()
request := &kmsapi.DecryptRequest{
Ciphertext: req.Ciphertext,
Uid: uid,
KeyId: req.KeyID,
Annotations: req.Annotations,
}
response, err := g.kmsClient.Decrypt(ctx, request)
if err != nil {
return nil, err
}
return response.Plaintext, nil
}
// Encrypt bytes to a string ciphertext.
func (g *gRPCService) Encrypt(ctx context.Context, uid string, plaintext []byte) (*EncryptResponse, error) {
ctx, cancel := context.WithTimeout(ctx, g.callTimeout)
defer cancel()
request := &kmsapi.EncryptRequest{
Plaintext: plaintext,
Uid: uid,
}
response, err := g.kmsClient.Encrypt(ctx, request)
if err != nil {
return nil, err
}
return &EncryptResponse{
Ciphertext: response.Ciphertext,
KeyID: response.KeyId,
Annotations: response.Annotations,
}, nil
}
// Status returns the status of the KMSv2 provider.
func (g *gRPCService) Status(ctx context.Context) (*StatusResponse, error) {
ctx, cancel := context.WithTimeout(ctx, g.callTimeout)
defer cancel()
request := &kmsapi.StatusRequest{}
response, err := g.kmsClient.Status(ctx, request)
if err != nil {
return nil, err
}
return &StatusResponse{Version: response.Version, Healthz: response.Healthz, KeyID: response.KeyId}, nil
}

View File

@@ -0,0 +1,9 @@
# See the OWNERS docs at https://go.k8s.io/owners
# Disable inheritance as this is an api owners file
options:
no_parent_owners: true
approvers:
- api-approvers
reviewers:
- sig-auth-api-reviewers

View File

@@ -0,0 +1,128 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: api.proto
package v2alpha1
import (
fmt "fmt"
proto "github.com/gogo/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// EncryptedObject is the representation of data stored in etcd after envelope encryption.
type EncryptedObject struct {
// EncryptedData is the encrypted data.
EncryptedData []byte `protobuf:"bytes,1,opt,name=encryptedData,proto3" json:"encryptedData,omitempty"`
// KeyID is the KMS key ID used for encryption operations.
KeyID string `protobuf:"bytes,2,opt,name=keyID,proto3" json:"keyID,omitempty"`
// EncryptedDEK is the encrypted DEK.
EncryptedDEK []byte `protobuf:"bytes,3,opt,name=encryptedDEK,proto3" json:"encryptedDEK,omitempty"`
// Annotations is additional metadata that was provided by the KMS plugin.
Annotations map[string][]byte `protobuf:"bytes,4,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EncryptedObject) Reset() { *m = EncryptedObject{} }
func (m *EncryptedObject) String() string { return proto.CompactTextString(m) }
func (*EncryptedObject) ProtoMessage() {}
func (*EncryptedObject) Descriptor() ([]byte, []int) {
return fileDescriptor_00212fb1f9d3bf1c, []int{0}
}
func (m *EncryptedObject) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EncryptedObject.Unmarshal(m, b)
}
func (m *EncryptedObject) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EncryptedObject.Marshal(b, m, deterministic)
}
func (m *EncryptedObject) XXX_Merge(src proto.Message) {
xxx_messageInfo_EncryptedObject.Merge(m, src)
}
func (m *EncryptedObject) XXX_Size() int {
return xxx_messageInfo_EncryptedObject.Size(m)
}
func (m *EncryptedObject) XXX_DiscardUnknown() {
xxx_messageInfo_EncryptedObject.DiscardUnknown(m)
}
var xxx_messageInfo_EncryptedObject proto.InternalMessageInfo
func (m *EncryptedObject) GetEncryptedData() []byte {
if m != nil {
return m.EncryptedData
}
return nil
}
func (m *EncryptedObject) GetKeyID() string {
if m != nil {
return m.KeyID
}
return ""
}
func (m *EncryptedObject) GetEncryptedDEK() []byte {
if m != nil {
return m.EncryptedDEK
}
return nil
}
func (m *EncryptedObject) GetAnnotations() map[string][]byte {
if m != nil {
return m.Annotations
}
return nil
}
func init() {
proto.RegisterType((*EncryptedObject)(nil), "v2alpha1.EncryptedObject")
proto.RegisterMapType((map[string][]byte)(nil), "v2alpha1.EncryptedObject.AnnotationsEntry")
}
func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) }
var fileDescriptor_00212fb1f9d3bf1c = []byte{
// 200 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4c, 0x2c, 0xc8, 0xd4,
0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x28, 0x33, 0x4a, 0xcc, 0x29, 0xc8, 0x48, 0x34, 0x54,
0xfa, 0xcf, 0xc8, 0xc5, 0xef, 0x9a, 0x97, 0x5c, 0x54, 0x59, 0x50, 0x92, 0x9a, 0xe2, 0x9f, 0x94,
0x95, 0x9a, 0x5c, 0x22, 0xa4, 0xc2, 0xc5, 0x9b, 0x0a, 0x13, 0x72, 0x49, 0x2c, 0x49, 0x94, 0x60,
0x54, 0x60, 0xd4, 0xe0, 0x09, 0x42, 0x15, 0x14, 0x12, 0xe1, 0x62, 0xcd, 0x4e, 0xad, 0xf4, 0x74,
0x91, 0x60, 0x52, 0x60, 0xd4, 0xe0, 0x0c, 0x82, 0x70, 0x84, 0x94, 0xb8, 0x78, 0x10, 0xca, 0x5c,
0xbd, 0x25, 0x98, 0xc1, 0x5a, 0x51, 0xc4, 0x84, 0x7c, 0xb8, 0xb8, 0x13, 0xf3, 0xf2, 0xf2, 0x4b,
0x12, 0x4b, 0x32, 0xf3, 0xf3, 0x8a, 0x25, 0x58, 0x14, 0x98, 0x35, 0xb8, 0x8d, 0xb4, 0xf4, 0x60,
0x6e, 0xd2, 0x43, 0x73, 0x8f, 0x9e, 0x23, 0x42, 0xb1, 0x6b, 0x5e, 0x49, 0x51, 0x65, 0x10, 0xb2,
0x76, 0x29, 0x3b, 0x2e, 0x01, 0x74, 0x05, 0x42, 0x02, 0x5c, 0xcc, 0xd9, 0xa9, 0x95, 0x60, 0x77,
0x73, 0x06, 0x81, 0x98, 0x20, 0xd7, 0x96, 0x25, 0xe6, 0x94, 0xa6, 0x82, 0x5d, 0xcb, 0x13, 0x04,
0xe1, 0x58, 0x31, 0x59, 0x30, 0x26, 0xb1, 0x81, 0x83, 0xc4, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff,
0x88, 0x8c, 0xbb, 0x4e, 0x1f, 0x01, 0x00, 0x00,
}

View File

@@ -0,0 +1,35 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// To regenerate api.pb.go run hack/update-generated-kms.sh
syntax = "proto3";
package v2alpha1;
// EncryptedObject is the representation of data stored in etcd after envelope encryption.
message EncryptedObject {
// EncryptedData is the encrypted data.
bytes encryptedData = 1;
// KeyID is the KMS key ID used for encryption operations.
string keyID = 2;
// EncryptedDEK is the encrypted DEK.
bytes encryptedDEK = 3;
// Annotations is additional metadata that was provided by the KMS plugin.
map<string, bytes> annotations = 4;
}

View File

@@ -0,0 +1,18 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package v2alpha1 contains definition of kms-plugin's serialized types.
package v2alpha1

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package envelope
package metrics
import (
"sync"
@@ -27,13 +27,13 @@ import (
const (
namespace = "apiserver"
subsystem = "envelope_encryption"
fromStorageLabel = "from_storage"
toStorageLabel = "to_storage"
FromStorageLabel = "from_storage"
ToStorageLabel = "to_storage"
)
/*
* By default, all the following metrics are defined as falling under
* ALPHA stability level https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/1209-metrics-stability/20190404-kubernetes-control-plane-metrics-stability.md#stability-classes)
* ALPHA stability level https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/1209-metrics-stability/kubernetes-control-plane-metrics-stability.md#stability-classes)
*
* Promoting the stability level of the metric is a responsibility of the component owner, since it
* involves explicitly acknowledging support for the metric across multiple releases, in accordance with
@@ -71,16 +71,16 @@ var (
var registerMetricsFunc sync.Once
func registerMetrics() {
func RegisterMetrics() {
registerMetricsFunc.Do(func() {
legacyregistry.MustRegister(dekCacheFillPercent)
legacyregistry.MustRegister(dekCacheInterArrivals)
})
}
func recordArrival(transformationType string, start time.Time) {
func RecordArrival(transformationType string, start time.Time) {
switch transformationType {
case fromStorageLabel:
case FromStorageLabel:
lockLastFromStorage.Lock()
defer lockLastFromStorage.Unlock()
@@ -89,7 +89,7 @@ func recordArrival(transformationType string, start time.Time) {
}
dekCacheInterArrivals.WithLabelValues(transformationType).Observe(start.Sub(lastFromStorage).Seconds())
lastFromStorage = start
case toStorageLabel:
case ToStorageLabel:
lockLastToStorage.Lock()
defer lockLastToStorage.Unlock()
@@ -100,3 +100,7 @@ func recordArrival(transformationType string, start time.Time) {
lastToStorage = start
}
}
func RecordDekCacheFillPercent(percent float64) {
dekCacheFillPercent.Set(percent)
}

View File

@@ -0,0 +1,54 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package util
import (
"fmt"
"net/url"
"strings"
)
const (
// unixProtocol is the only supported protocol for remote KMS provider.
unixProtocol = "unix"
)
// Parse the endpoint to extract schema, host or path.
func ParseEndpoint(endpoint string) (string, error) {
if len(endpoint) == 0 {
return "", fmt.Errorf("remote KMS provider can't use empty string as endpoint")
}
u, err := url.Parse(endpoint)
if err != nil {
return "", fmt.Errorf("invalid endpoint %q for remote KMS provider, error: %v", endpoint, err)
}
if u.Scheme != unixProtocol {
return "", fmt.Errorf("unsupported scheme %q for remote KMS provider", u.Scheme)
}
// Linux abstract namespace socket - no physical file required
// Warning: Linux Abstract sockets have not concept of ACL (unlike traditional file based sockets).
// However, Linux Abstract sockets are subject to Linux networking namespace, so will only be accessible to
// containers within the same pod (unless host networking is used).
if strings.HasPrefix(u.Path, "/@") {
return strings.TrimPrefix(u.Path, "/"), nil
}
return u.Path, nil
}

View File

@@ -15,7 +15,7 @@ limitations under the License.
*/
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: service.proto
// source: api.proto
package v1beta1
@@ -52,7 +52,7 @@ func (m *VersionRequest) Reset() { *m = VersionRequest{} }
func (m *VersionRequest) String() string { return proto.CompactTextString(m) }
func (*VersionRequest) ProtoMessage() {}
func (*VersionRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_a0b84a42fa06f626, []int{0}
return fileDescriptor_00212fb1f9d3bf1c, []int{0}
}
func (m *VersionRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_VersionRequest.Unmarshal(m, b)
@@ -95,7 +95,7 @@ func (m *VersionResponse) Reset() { *m = VersionResponse{} }
func (m *VersionResponse) String() string { return proto.CompactTextString(m) }
func (*VersionResponse) ProtoMessage() {}
func (*VersionResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_a0b84a42fa06f626, []int{1}
return fileDescriptor_00212fb1f9d3bf1c, []int{1}
}
func (m *VersionResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_VersionResponse.Unmarshal(m, b)
@@ -150,7 +150,7 @@ func (m *DecryptRequest) Reset() { *m = DecryptRequest{} }
func (m *DecryptRequest) String() string { return proto.CompactTextString(m) }
func (*DecryptRequest) ProtoMessage() {}
func (*DecryptRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_a0b84a42fa06f626, []int{2}
return fileDescriptor_00212fb1f9d3bf1c, []int{2}
}
func (m *DecryptRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DecryptRequest.Unmarshal(m, b)
@@ -196,7 +196,7 @@ func (m *DecryptResponse) Reset() { *m = DecryptResponse{} }
func (m *DecryptResponse) String() string { return proto.CompactTextString(m) }
func (*DecryptResponse) ProtoMessage() {}
func (*DecryptResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_a0b84a42fa06f626, []int{3}
return fileDescriptor_00212fb1f9d3bf1c, []int{3}
}
func (m *DecryptResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DecryptResponse.Unmarshal(m, b)
@@ -237,7 +237,7 @@ func (m *EncryptRequest) Reset() { *m = EncryptRequest{} }
func (m *EncryptRequest) String() string { return proto.CompactTextString(m) }
func (*EncryptRequest) ProtoMessage() {}
func (*EncryptRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_a0b84a42fa06f626, []int{4}
return fileDescriptor_00212fb1f9d3bf1c, []int{4}
}
func (m *EncryptRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EncryptRequest.Unmarshal(m, b)
@@ -283,7 +283,7 @@ func (m *EncryptResponse) Reset() { *m = EncryptResponse{} }
func (m *EncryptResponse) String() string { return proto.CompactTextString(m) }
func (*EncryptResponse) ProtoMessage() {}
func (*EncryptResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_a0b84a42fa06f626, []int{5}
return fileDescriptor_00212fb1f9d3bf1c, []int{5}
}
func (m *EncryptResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EncryptResponse.Unmarshal(m, b)
@@ -319,28 +319,28 @@ func init() {
proto.RegisterType((*EncryptResponse)(nil), "v1beta1.EncryptResponse")
}
func init() { proto.RegisterFile("service.proto", fileDescriptor_a0b84a42fa06f626) }
func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) }
var fileDescriptor_a0b84a42fa06f626 = []byte{
// 287 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0xcd, 0x4a, 0xc4, 0x30,
0x10, 0xde, 0xae, 0xb8, 0xc5, 0xb1, 0xb6, 0x10, 0x16, 0x2d, 0x9e, 0x34, 0x97, 0x55, 0x0f, 0x85,
0xd5, 0xbb, 0x88, 0xe8, 0x49, 0xf4, 0x50, 0xc1, 0xab, 0x64, 0xcb, 0xa0, 0x05, 0x9b, 0xc6, 0x24,
0x5b, 0xd9, 0x17, 0xf5, 0x79, 0xc4, 0x66, 0x5a, 0xd3, 0x15, 0x71, 0x8f, 0x33, 0x99, 0xef, 0x6f,
0x26, 0xb0, 0x67, 0x50, 0x37, 0x65, 0x81, 0x99, 0xd2, 0xb5, 0xad, 0x59, 0xd8, 0xcc, 0x17, 0x68,
0xc5, 0x9c, 0x9f, 0x41, 0xfc, 0x84, 0xda, 0x94, 0xb5, 0xcc, 0xf1, 0x7d, 0x89, 0xc6, 0xb2, 0x14,
0xc2, 0xc6, 0x75, 0xd2, 0xe0, 0x28, 0x38, 0xd9, 0xc9, 0xbb, 0x92, 0x7f, 0x40, 0xd2, 0xcf, 0x1a,
0x55, 0x4b, 0x83, 0x7f, 0x0f, 0xb3, 0x63, 0x88, 0xf4, 0x52, 0xda, 0xb2, 0xc2, 0x67, 0x29, 0x2a,
0x4c, 0xc7, 0xed, 0xf3, 0x2e, 0xf5, 0x1e, 0x44, 0x85, 0x6c, 0x06, 0x49, 0x37, 0xd2, 0x91, 0x6c,
0xb5, 0x53, 0x31, 0xb5, 0x49, 0x8d, 0x5f, 0x43, 0x7c, 0x83, 0x85, 0x5e, 0x29, 0xfb, 0xaf, 0x49,
0xb6, 0x0f, 0x93, 0xa2, 0x54, 0xaf, 0xa8, 0x5b, 0xc5, 0x28, 0xa7, 0x8a, 0xcf, 0x20, 0xe9, 0x39,
0xc8, 0xfc, 0x14, 0xb6, 0xd5, 0x9b, 0x28, 0x1d, 0x45, 0x94, 0xbb, 0x82, 0x5f, 0x41, 0x7c, 0x2b,
0x37, 0x14, 0xeb, 0x19, 0xc6, 0x3e, 0xc3, 0x29, 0x24, 0x3d, 0x03, 0x49, 0xfd, 0xb8, 0x0a, 0x7c,
0x57, 0xe7, 0x9f, 0x01, 0x4c, 0xef, 0x70, 0x75, 0x2f, 0xa4, 0x78, 0xc1, 0x0a, 0xa5, 0x7d, 0x74,
0x67, 0x62, 0x97, 0x10, 0x52, 0x7a, 0x76, 0x90, 0xd1, 0xb1, 0xb2, 0xe1, 0xa5, 0x0e, 0xd3, 0xdf,
0x0f, 0x4e, 0x8e, 0x8f, 0xbe, 0xf1, 0x14, 0xd7, 0xc3, 0x0f, 0x97, 0xe8, 0xe1, 0xd7, 0x36, 0xe3,
0xf0, 0x94, 0xc1, 0xc3, 0x0f, 0xf7, 0xe2, 0xe1, 0xd7, 0xe2, 0xf2, 0xd1, 0x62, 0xd2, 0xfe, 0xb3,
0x8b, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x33, 0x8d, 0x09, 0xe1, 0x78, 0x02, 0x00, 0x00,
var fileDescriptor_00212fb1f9d3bf1c = []byte{
// 286 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x4f, 0x4b, 0xc3, 0x30,
0x14, 0x5f, 0x27, 0xae, 0xec, 0x59, 0x5a, 0x08, 0x43, 0x8b, 0x27, 0xcd, 0x65, 0xea, 0xa1, 0x30,
0xbd, 0x8b, 0x88, 0x9e, 0x44, 0x0f, 0x15, 0xbc, 0x4a, 0x56, 0x1e, 0x1a, 0xb0, 0x69, 0x4c, 0xb3,
0xca, 0xbe, 0xa8, 0x9f, 0x47, 0x6c, 0x5e, 0x6b, 0x3a, 0x11, 0x77, 0x7c, 0x2f, 0xef, 0xf7, 0xef,
0xbd, 0xc0, 0x54, 0x68, 0x99, 0x69, 0x53, 0xd9, 0x8a, 0x85, 0xcd, 0x62, 0x89, 0x56, 0x2c, 0xf8,
0x19, 0xc4, 0x4f, 0x68, 0x6a, 0x59, 0xa9, 0x1c, 0xdf, 0x57, 0x58, 0x5b, 0x96, 0x42, 0xd8, 0xb8,
0x4e, 0x1a, 0x1c, 0x05, 0x27, 0xd3, 0xbc, 0x2b, 0xf9, 0x07, 0x24, 0xfd, 0x6c, 0xad, 0x2b, 0x55,
0xe3, 0xdf, 0xc3, 0xec, 0x18, 0x22, 0xb3, 0x52, 0x56, 0x96, 0xf8, 0xac, 0x44, 0x89, 0xe9, 0xb8,
0x7d, 0xde, 0xa3, 0xde, 0x83, 0x28, 0x91, 0xcd, 0x21, 0xe9, 0x46, 0x3a, 0x92, 0x9d, 0x76, 0x2a,
0xa6, 0x36, 0xa9, 0xf1, 0x6b, 0x88, 0x6f, 0xb0, 0x30, 0x6b, 0x6d, 0xff, 0x35, 0xc9, 0xf6, 0x61,
0x52, 0x48, 0xfd, 0x8a, 0xa6, 0x55, 0x8c, 0x72, 0xaa, 0xf8, 0x1c, 0x92, 0x9e, 0x83, 0xcc, 0xcf,
0x60, 0x57, 0xbf, 0x09, 0xe9, 0x28, 0xa2, 0xdc, 0x15, 0xfc, 0x0a, 0xe2, 0x5b, 0xb5, 0xa5, 0x58,
0xcf, 0x30, 0xf6, 0x19, 0x4e, 0x21, 0xe9, 0x19, 0x48, 0xea, 0xc7, 0x55, 0xe0, 0xbb, 0x3a, 0xff,
0x0c, 0x60, 0x76, 0x87, 0xeb, 0x7b, 0xa1, 0xc4, 0x0b, 0x96, 0xa8, 0xec, 0x23, 0x9a, 0x46, 0x16,
0xc8, 0x2e, 0x21, 0xa4, 0xf4, 0xec, 0x20, 0xa3, 0x63, 0x65, 0xc3, 0x4b, 0x1d, 0xa6, 0xbf, 0x1f,
0x9c, 0x1c, 0x1f, 0x7d, 0xe3, 0x29, 0xae, 0x87, 0x1f, 0x2e, 0xd1, 0xc3, 0x6f, 0x6c, 0xc6, 0xe1,
0x29, 0x83, 0x87, 0x1f, 0xee, 0xc5, 0xc3, 0x6f, 0xc4, 0xe5, 0xa3, 0xe5, 0xa4, 0xfd, 0x67, 0x17,
0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x57, 0xc8, 0x65, 0x5a, 0x74, 0x02, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -498,5 +498,5 @@ var _KeyManagementService_serviceDesc = grpc.ServiceDesc{
},
},
Streams: []grpc.StreamDesc{},
Metadata: "service.proto",
Metadata: "api.proto",
}

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// To regenerate service.pb.go run hack/update-generated-kms.sh
// To regenerate api.pb.go run hack/update-generated-kms.sh
syntax = "proto3";
package v1beta1;

View File

@@ -0,0 +1,542 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: api.proto
package v2alpha1
import (
context "context"
fmt "fmt"
proto "github.com/gogo/protobuf/proto"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type StatusRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *StatusRequest) Reset() { *m = StatusRequest{} }
func (m *StatusRequest) String() string { return proto.CompactTextString(m) }
func (*StatusRequest) ProtoMessage() {}
func (*StatusRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_00212fb1f9d3bf1c, []int{0}
}
func (m *StatusRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StatusRequest.Unmarshal(m, b)
}
func (m *StatusRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_StatusRequest.Marshal(b, m, deterministic)
}
func (m *StatusRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_StatusRequest.Merge(m, src)
}
func (m *StatusRequest) XXX_Size() int {
return xxx_messageInfo_StatusRequest.Size(m)
}
func (m *StatusRequest) XXX_DiscardUnknown() {
xxx_messageInfo_StatusRequest.DiscardUnknown(m)
}
var xxx_messageInfo_StatusRequest proto.InternalMessageInfo
type StatusResponse struct {
// Version of the KMS plugin API. Must match the configured .resources[].providers[].kms.apiVersion
Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
// Any value other than "ok" is failing healthz. On failure, the associated API server healthz endpoint will contain this value as part of the error message.
Healthz string `protobuf:"bytes,2,opt,name=healthz,proto3" json:"healthz,omitempty"`
// the current write key, used to determine staleness of data updated via value.Transformer.TransformFromStorage.
KeyId string `protobuf:"bytes,3,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *StatusResponse) Reset() { *m = StatusResponse{} }
func (m *StatusResponse) String() string { return proto.CompactTextString(m) }
func (*StatusResponse) ProtoMessage() {}
func (*StatusResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_00212fb1f9d3bf1c, []int{1}
}
func (m *StatusResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StatusResponse.Unmarshal(m, b)
}
func (m *StatusResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_StatusResponse.Marshal(b, m, deterministic)
}
func (m *StatusResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_StatusResponse.Merge(m, src)
}
func (m *StatusResponse) XXX_Size() int {
return xxx_messageInfo_StatusResponse.Size(m)
}
func (m *StatusResponse) XXX_DiscardUnknown() {
xxx_messageInfo_StatusResponse.DiscardUnknown(m)
}
var xxx_messageInfo_StatusResponse proto.InternalMessageInfo
func (m *StatusResponse) GetVersion() string {
if m != nil {
return m.Version
}
return ""
}
func (m *StatusResponse) GetHealthz() string {
if m != nil {
return m.Healthz
}
return ""
}
func (m *StatusResponse) GetKeyId() string {
if m != nil {
return m.KeyId
}
return ""
}
type DecryptRequest struct {
// The data to be decrypted.
Ciphertext []byte `protobuf:"bytes,1,opt,name=ciphertext,proto3" json:"ciphertext,omitempty"`
// UID is a unique identifier for the request.
Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"`
// The keyID that was provided to the apiserver during encryption.
// This represents the KMS KEK that was used to encrypt the data.
KeyId string `protobuf:"bytes,3,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"`
// Additional metadata that was sent by the KMS plugin during encryption.
Annotations map[string][]byte `protobuf:"bytes,4,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *DecryptRequest) Reset() { *m = DecryptRequest{} }
func (m *DecryptRequest) String() string { return proto.CompactTextString(m) }
func (*DecryptRequest) ProtoMessage() {}
func (*DecryptRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_00212fb1f9d3bf1c, []int{2}
}
func (m *DecryptRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DecryptRequest.Unmarshal(m, b)
}
func (m *DecryptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_DecryptRequest.Marshal(b, m, deterministic)
}
func (m *DecryptRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_DecryptRequest.Merge(m, src)
}
func (m *DecryptRequest) XXX_Size() int {
return xxx_messageInfo_DecryptRequest.Size(m)
}
func (m *DecryptRequest) XXX_DiscardUnknown() {
xxx_messageInfo_DecryptRequest.DiscardUnknown(m)
}
var xxx_messageInfo_DecryptRequest proto.InternalMessageInfo
func (m *DecryptRequest) GetCiphertext() []byte {
if m != nil {
return m.Ciphertext
}
return nil
}
func (m *DecryptRequest) GetUid() string {
if m != nil {
return m.Uid
}
return ""
}
func (m *DecryptRequest) GetKeyId() string {
if m != nil {
return m.KeyId
}
return ""
}
func (m *DecryptRequest) GetAnnotations() map[string][]byte {
if m != nil {
return m.Annotations
}
return nil
}
type DecryptResponse struct {
// The decrypted data.
Plaintext []byte `protobuf:"bytes,1,opt,name=plaintext,proto3" json:"plaintext,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *DecryptResponse) Reset() { *m = DecryptResponse{} }
func (m *DecryptResponse) String() string { return proto.CompactTextString(m) }
func (*DecryptResponse) ProtoMessage() {}
func (*DecryptResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_00212fb1f9d3bf1c, []int{3}
}
func (m *DecryptResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DecryptResponse.Unmarshal(m, b)
}
func (m *DecryptResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_DecryptResponse.Marshal(b, m, deterministic)
}
func (m *DecryptResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_DecryptResponse.Merge(m, src)
}
func (m *DecryptResponse) XXX_Size() int {
return xxx_messageInfo_DecryptResponse.Size(m)
}
func (m *DecryptResponse) XXX_DiscardUnknown() {
xxx_messageInfo_DecryptResponse.DiscardUnknown(m)
}
var xxx_messageInfo_DecryptResponse proto.InternalMessageInfo
func (m *DecryptResponse) GetPlaintext() []byte {
if m != nil {
return m.Plaintext
}
return nil
}
type EncryptRequest struct {
// The data to be encrypted.
Plaintext []byte `protobuf:"bytes,1,opt,name=plaintext,proto3" json:"plaintext,omitempty"`
// UID is a unique identifier for the request.
Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EncryptRequest) Reset() { *m = EncryptRequest{} }
func (m *EncryptRequest) String() string { return proto.CompactTextString(m) }
func (*EncryptRequest) ProtoMessage() {}
func (*EncryptRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_00212fb1f9d3bf1c, []int{4}
}
func (m *EncryptRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EncryptRequest.Unmarshal(m, b)
}
func (m *EncryptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EncryptRequest.Marshal(b, m, deterministic)
}
func (m *EncryptRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_EncryptRequest.Merge(m, src)
}
func (m *EncryptRequest) XXX_Size() int {
return xxx_messageInfo_EncryptRequest.Size(m)
}
func (m *EncryptRequest) XXX_DiscardUnknown() {
xxx_messageInfo_EncryptRequest.DiscardUnknown(m)
}
var xxx_messageInfo_EncryptRequest proto.InternalMessageInfo
func (m *EncryptRequest) GetPlaintext() []byte {
if m != nil {
return m.Plaintext
}
return nil
}
func (m *EncryptRequest) GetUid() string {
if m != nil {
return m.Uid
}
return ""
}
type EncryptResponse struct {
// The encrypted data.
Ciphertext []byte `protobuf:"bytes,1,opt,name=ciphertext,proto3" json:"ciphertext,omitempty"`
// The KMS key ID used to encrypt the data. This must always refer to the KMS KEK and not any local KEKs that may be in use.
// This can be used to inform staleness of data updated via value.Transformer.TransformFromStorage.
KeyId string `protobuf:"bytes,2,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"`
// Additional metadata to be stored with the encrypted data.
// This metadata can contain the encrypted local KEK that was used to encrypt the DEK.
// This data is stored in plaintext in etcd. KMS plugin implementations are responsible for pre-encrypting any sensitive data.
Annotations map[string][]byte `protobuf:"bytes,3,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EncryptResponse) Reset() { *m = EncryptResponse{} }
func (m *EncryptResponse) String() string { return proto.CompactTextString(m) }
func (*EncryptResponse) ProtoMessage() {}
func (*EncryptResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_00212fb1f9d3bf1c, []int{5}
}
func (m *EncryptResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EncryptResponse.Unmarshal(m, b)
}
func (m *EncryptResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EncryptResponse.Marshal(b, m, deterministic)
}
func (m *EncryptResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_EncryptResponse.Merge(m, src)
}
func (m *EncryptResponse) XXX_Size() int {
return xxx_messageInfo_EncryptResponse.Size(m)
}
func (m *EncryptResponse) XXX_DiscardUnknown() {
xxx_messageInfo_EncryptResponse.DiscardUnknown(m)
}
var xxx_messageInfo_EncryptResponse proto.InternalMessageInfo
func (m *EncryptResponse) GetCiphertext() []byte {
if m != nil {
return m.Ciphertext
}
return nil
}
func (m *EncryptResponse) GetKeyId() string {
if m != nil {
return m.KeyId
}
return ""
}
func (m *EncryptResponse) GetAnnotations() map[string][]byte {
if m != nil {
return m.Annotations
}
return nil
}
func init() {
proto.RegisterType((*StatusRequest)(nil), "v2alpha1.StatusRequest")
proto.RegisterType((*StatusResponse)(nil), "v2alpha1.StatusResponse")
proto.RegisterType((*DecryptRequest)(nil), "v2alpha1.DecryptRequest")
proto.RegisterMapType((map[string][]byte)(nil), "v2alpha1.DecryptRequest.AnnotationsEntry")
proto.RegisterType((*DecryptResponse)(nil), "v2alpha1.DecryptResponse")
proto.RegisterType((*EncryptRequest)(nil), "v2alpha1.EncryptRequest")
proto.RegisterType((*EncryptResponse)(nil), "v2alpha1.EncryptResponse")
proto.RegisterMapType((map[string][]byte)(nil), "v2alpha1.EncryptResponse.AnnotationsEntry")
}
func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) }
var fileDescriptor_00212fb1f9d3bf1c = []byte{
// 391 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0xcf, 0x4f, 0xe2, 0x40,
0x14, 0xc7, 0x29, 0x5d, 0x60, 0x79, 0xb0, 0x40, 0x26, 0x6c, 0xb6, 0x4b, 0x36, 0x1b, 0x32, 0x27,
0x76, 0x0f, 0xdd, 0x2c, 0x5e, 0x8c, 0x89, 0x06, 0x13, 0x39, 0x18, 0xf4, 0x52, 0x8e, 0x1e, 0xcc,
0x08, 0x2f, 0x76, 0x42, 0x9d, 0xd6, 0x76, 0xda, 0x58, 0xff, 0x50, 0x13, 0xff, 0x01, 0xff, 0x0e,
0xd3, 0x76, 0xa0, 0x2d, 0x88, 0x9e, 0xbc, 0xcd, 0xfb, 0xd1, 0xef, 0xf7, 0xcd, 0x67, 0x5e, 0xa1,
0xc9, 0x3c, 0x6e, 0x7a, 0xbe, 0x2b, 0x5d, 0xf2, 0x35, 0x1a, 0x33, 0xc7, 0xb3, 0xd9, 0x7f, 0xda,
0x85, 0x6f, 0x73, 0xc9, 0x64, 0x18, 0x58, 0x78, 0x1f, 0x62, 0x20, 0xe9, 0x15, 0x74, 0xd6, 0x89,
0xc0, 0x73, 0x45, 0x80, 0xc4, 0x80, 0x46, 0x84, 0x7e, 0xc0, 0x5d, 0x61, 0x68, 0x43, 0x6d, 0xd4,
0xb4, 0xd6, 0x61, 0x52, 0xb1, 0x91, 0x39, 0xd2, 0x7e, 0x34, 0xaa, 0x59, 0x45, 0x85, 0xe4, 0x3b,
0xd4, 0x57, 0x18, 0x5f, 0xf3, 0xa5, 0xa1, 0xa7, 0x85, 0xda, 0x0a, 0xe3, 0xf3, 0x25, 0x7d, 0xd1,
0xa0, 0x73, 0x86, 0x0b, 0x3f, 0xf6, 0xa4, 0xf2, 0x23, 0xbf, 0x01, 0x16, 0xdc, 0xb3, 0xd1, 0x97,
0xf8, 0x20, 0x53, 0x83, 0xb6, 0x55, 0xc8, 0x90, 0x1e, 0xe8, 0x21, 0x5f, 0x2a, 0xfd, 0xe4, 0xb8,
0x47, 0x9b, 0xcc, 0xa0, 0xc5, 0x84, 0x70, 0x25, 0x93, 0xdc, 0x15, 0x81, 0xf1, 0x65, 0xa8, 0x8f,
0x5a, 0xe3, 0x3f, 0xe6, 0xfa, 0xa6, 0x66, 0xd9, 0xd7, 0x3c, 0xcd, 0x7b, 0xa7, 0x42, 0xfa, 0xb1,
0x55, 0xfc, 0x7a, 0x70, 0x02, 0xbd, 0xed, 0x86, 0x64, 0x92, 0x15, 0xc6, 0x8a, 0x41, 0x72, 0x24,
0x7d, 0xa8, 0x45, 0xcc, 0x09, 0x31, 0x9d, 0xae, 0x6d, 0x65, 0xc1, 0x51, 0xf5, 0x50, 0xa3, 0xff,
0xa0, 0xbb, 0xf1, 0x53, 0x18, 0x7f, 0x41, 0xd3, 0x73, 0x18, 0x17, 0x85, 0x7b, 0xe6, 0x09, 0x3a,
0x81, 0xce, 0x54, 0x94, 0xc0, 0xbc, 0xdb, 0xbf, 0x8b, 0x85, 0x3e, 0x69, 0xd0, 0xdd, 0x48, 0x28,
0xcf, 0x8f, 0xe0, 0xe6, 0x28, 0xab, 0x45, 0x94, 0x17, 0x65, 0x94, 0x7a, 0x8a, 0xf2, 0x6f, 0x8e,
0x72, 0xcb, 0xe6, 0x73, 0x59, 0x8e, 0x9f, 0x35, 0xe8, 0xcf, 0x30, 0xbe, 0x64, 0x82, 0xdd, 0xe2,
0x1d, 0x0a, 0x39, 0x47, 0x3f, 0xe2, 0x0b, 0x24, 0xc7, 0x50, 0xcf, 0x56, 0x95, 0xfc, 0xc8, 0x67,
0x2b, 0x6d, 0xf3, 0xc0, 0xd8, 0x2d, 0x64, 0x33, 0xd3, 0x0a, 0x99, 0x40, 0x43, 0xbd, 0x11, 0x31,
0xf6, 0xad, 0xc9, 0xe0, 0xe7, 0x1b, 0x95, 0xa2, 0x82, 0x42, 0x51, 0x54, 0x28, 0xbf, 0x63, 0x51,
0x61, 0x8b, 0x1b, 0xad, 0xdc, 0xd4, 0xd3, 0xff, 0xf1, 0xe0, 0x35, 0x00, 0x00, 0xff, 0xff, 0xa7,
0xdd, 0xa1, 0x79, 0x9c, 0x03, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// KeyManagementServiceClient is the client API for KeyManagementService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type KeyManagementServiceClient interface {
// this API is meant to be polled
Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error)
// Execute decryption operation in KMS provider.
Decrypt(ctx context.Context, in *DecryptRequest, opts ...grpc.CallOption) (*DecryptResponse, error)
// Execute encryption operation in KMS provider.
Encrypt(ctx context.Context, in *EncryptRequest, opts ...grpc.CallOption) (*EncryptResponse, error)
}
type keyManagementServiceClient struct {
cc *grpc.ClientConn
}
func NewKeyManagementServiceClient(cc *grpc.ClientConn) KeyManagementServiceClient {
return &keyManagementServiceClient{cc}
}
func (c *keyManagementServiceClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) {
out := new(StatusResponse)
err := c.cc.Invoke(ctx, "/v2alpha1.KeyManagementService/Status", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *keyManagementServiceClient) Decrypt(ctx context.Context, in *DecryptRequest, opts ...grpc.CallOption) (*DecryptResponse, error) {
out := new(DecryptResponse)
err := c.cc.Invoke(ctx, "/v2alpha1.KeyManagementService/Decrypt", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *keyManagementServiceClient) Encrypt(ctx context.Context, in *EncryptRequest, opts ...grpc.CallOption) (*EncryptResponse, error) {
out := new(EncryptResponse)
err := c.cc.Invoke(ctx, "/v2alpha1.KeyManagementService/Encrypt", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// KeyManagementServiceServer is the server API for KeyManagementService service.
type KeyManagementServiceServer interface {
// this API is meant to be polled
Status(context.Context, *StatusRequest) (*StatusResponse, error)
// Execute decryption operation in KMS provider.
Decrypt(context.Context, *DecryptRequest) (*DecryptResponse, error)
// Execute encryption operation in KMS provider.
Encrypt(context.Context, *EncryptRequest) (*EncryptResponse, error)
}
// UnimplementedKeyManagementServiceServer can be embedded to have forward compatible implementations.
type UnimplementedKeyManagementServiceServer struct {
}
func (*UnimplementedKeyManagementServiceServer) Status(ctx context.Context, req *StatusRequest) (*StatusResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Status not implemented")
}
func (*UnimplementedKeyManagementServiceServer) Decrypt(ctx context.Context, req *DecryptRequest) (*DecryptResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Decrypt not implemented")
}
func (*UnimplementedKeyManagementServiceServer) Encrypt(ctx context.Context, req *EncryptRequest) (*EncryptResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Encrypt not implemented")
}
func RegisterKeyManagementServiceServer(s *grpc.Server, srv KeyManagementServiceServer) {
s.RegisterService(&_KeyManagementService_serviceDesc, srv)
}
func _KeyManagementService_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(StatusRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(KeyManagementServiceServer).Status(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/v2alpha1.KeyManagementService/Status",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(KeyManagementServiceServer).Status(ctx, req.(*StatusRequest))
}
return interceptor(ctx, in, info, handler)
}
func _KeyManagementService_Decrypt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DecryptRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(KeyManagementServiceServer).Decrypt(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/v2alpha1.KeyManagementService/Decrypt",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(KeyManagementServiceServer).Decrypt(ctx, req.(*DecryptRequest))
}
return interceptor(ctx, in, info, handler)
}
func _KeyManagementService_Encrypt_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(EncryptRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(KeyManagementServiceServer).Encrypt(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/v2alpha1.KeyManagementService/Encrypt",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(KeyManagementServiceServer).Encrypt(ctx, req.(*EncryptRequest))
}
return interceptor(ctx, in, info, handler)
}
var _KeyManagementService_serviceDesc = grpc.ServiceDesc{
ServiceName: "v2alpha1.KeyManagementService",
HandlerType: (*KeyManagementServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Status",
Handler: _KeyManagementService_Status_Handler,
},
{
MethodName: "Decrypt",
Handler: _KeyManagementService_Decrypt_Handler,
},
{
MethodName: "Encrypt",
Handler: _KeyManagementService_Encrypt_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "api.proto",
}

View File

@@ -0,0 +1,78 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// To regenerate api.pb.go run hack/update-generated-kms.sh
syntax = "proto3";
package v2alpha1;
// This service defines the public APIs for remote KMS provider.
service KeyManagementService {
// this API is meant to be polled
rpc Status(StatusRequest) returns (StatusResponse) {}
// Execute decryption operation in KMS provider.
rpc Decrypt(DecryptRequest) returns (DecryptResponse) {}
// Execute encryption operation in KMS provider.
rpc Encrypt(EncryptRequest) returns (EncryptResponse) {}
}
message StatusRequest {}
message StatusResponse {
// Version of the KMS plugin API. Must match the configured .resources[].providers[].kms.apiVersion
string version = 1;
// Any value other than "ok" is failing healthz. On failure, the associated API server healthz endpoint will contain this value as part of the error message.
string healthz = 2;
// the current write key, used to determine staleness of data updated via value.Transformer.TransformFromStorage.
string key_id = 3;
}
message DecryptRequest {
// The data to be decrypted.
bytes ciphertext = 1;
// UID is a unique identifier for the request.
string uid = 2;
// The keyID that was provided to the apiserver during encryption.
// This represents the KMS KEK that was used to encrypt the data.
string key_id = 3;
// Additional metadata that was sent by the KMS plugin during encryption.
map<string, bytes> annotations = 4;
}
message DecryptResponse {
// The decrypted data.
bytes plaintext = 1;
}
message EncryptRequest {
// The data to be encrypted.
bytes plaintext = 1;
// UID is a unique identifier for the request.
string uid = 2;
}
message EncryptResponse {
// The encrypted data.
bytes ciphertext = 1;
// The KMS key ID used to encrypt the data. This must always refer to the KMS KEK and not any local KEKs that may be in use.
// This can be used to inform staleness of data updated via value.Transformer.TransformFromStorage.
string key_id = 2;
// Additional metadata to be stored with the encrypted data.
// This metadata can contain the encrypted local KEK that was used to encrypt the DEK.
// This data is stored in plaintext in etcd. KMS plugin implementations are responsible for pre-encrypting any sensitive data.
map<string, bytes> annotations = 3;
}

View File

@@ -0,0 +1,18 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package v2alpha1 contains definition of kms-plugin's gRPC service.
package v2alpha1

View File

@@ -18,6 +18,7 @@ package identity
import (
"bytes"
"context"
"fmt"
"k8s.io/apiserver/pkg/storage/value"
@@ -34,17 +35,17 @@ func NewEncryptCheckTransformer() value.Transformer {
}
// TransformFromStorage returns the input bytes if the data is not encrypted
func (identityTransformer) TransformFromStorage(b []byte, context value.Context) ([]byte, bool, error) {
func (identityTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) {
// identityTransformer has to return an error if the data is encoded using another transformer.
// JSON data starts with '{'. Protobuf data has a prefix 'k8s[\x00-\xFF]'.
// Prefix 'k8s:enc:' is reserved for encrypted data on disk.
if bytes.HasPrefix(b, []byte("k8s:enc:")) {
if bytes.HasPrefix(data, []byte("k8s:enc:")) {
return []byte{}, false, fmt.Errorf("identity transformer tried to read encrypted data")
}
return b, false, nil
return data, false, nil
}
// TransformToStorage implements the Transformer interface for identityTransformer
func (identityTransformer) TransformToStorage(b []byte, context value.Context) ([]byte, error) {
return b, nil
func (identityTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) {
return data, nil
}

View File

@@ -18,6 +18,7 @@ limitations under the License.
package secretbox
import (
"context"
"crypto/rand"
"fmt"
@@ -41,7 +42,7 @@ func NewSecretboxTransformer(key [32]byte) value.Transformer {
return &secretboxTransformer{key: key}
}
func (t *secretboxTransformer) TransformFromStorage(data []byte, context value.Context) ([]byte, bool, error) {
func (t *secretboxTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, bool, error) {
if len(data) < (secretbox.Overhead + nonceSize) {
return nil, false, fmt.Errorf("the stored data was shorter than the required size")
}
@@ -56,7 +57,7 @@ func (t *secretboxTransformer) TransformFromStorage(data []byte, context value.C
return result, false, nil
}
func (t *secretboxTransformer) TransformToStorage(data []byte, context value.Context) ([]byte, error) {
func (t *secretboxTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx value.Context) ([]byte, error) {
var nonce [nonceSize]byte
n, err := rand.Read(nonce[:])
if err != nil {

View File

@@ -33,7 +33,7 @@ const (
/*
* By default, all the following metrics are defined as falling under
* ALPHA stability level https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/1209-metrics-stability/20190404-kubernetes-control-plane-metrics-stability.md#stability-classes)
* ALPHA stability level https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/1209-metrics-stability/kubernetes-control-plane-metrics-stability.md#stability-classes)
*
* Promoting the stability level of the metric is a responsibility of the component owner, since it
* involves explicitly acknowledging support for the metric across multiple releases, in accordance with
@@ -47,8 +47,8 @@ var (
Name: "transformation_duration_seconds",
Help: "Latencies in seconds of value transformation operations.",
// In-process transformations (ex. AES CBC) complete on the order of 20 microseconds. However, when
// external KMS is involved latencies may climb into milliseconds.
Buckets: metrics.ExponentialBuckets(5e-6, 2, 14),
// external KMS is involved latencies may climb into hundreds of milliseconds.
Buckets: metrics.ExponentialBuckets(5e-6, 2, 25),
StabilityLevel: metrics.ALPHA,
},
[]string{"transformation_type"},

View File

@@ -19,6 +19,7 @@ package value
import (
"bytes"
"context"
"fmt"
"sync"
"time"
@@ -45,9 +46,9 @@ type Transformer interface {
// TransformFromStorage may transform the provided data from its underlying storage representation or return an error.
// Stale is true if the object on disk is stale and a write to etcd should be issued, even if the contents of the object
// have not changed.
TransformFromStorage(data []byte, context Context) (out []byte, stale bool, err error)
TransformFromStorage(ctx context.Context, data []byte, dataCtx Context) (out []byte, stale bool, err error)
// TransformToStorage may transform the provided data into the appropriate form in storage or return an error.
TransformToStorage(data []byte, context Context) (out []byte, err error)
TransformToStorage(ctx context.Context, data []byte, dataCtx Context) (out []byte, err error)
}
type identityTransformer struct{}
@@ -55,11 +56,11 @@ type identityTransformer struct{}
// IdentityTransformer performs no transformation of the provided data.
var IdentityTransformer Transformer = identityTransformer{}
func (identityTransformer) TransformFromStorage(b []byte, ctx Context) ([]byte, bool, error) {
return b, false, nil
func (identityTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx Context) ([]byte, bool, error) {
return data, false, nil
}
func (identityTransformer) TransformToStorage(b []byte, ctx Context) ([]byte, error) {
return b, nil
func (identityTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx Context) ([]byte, error) {
return data, nil
}
// DefaultContext is a simple implementation of Context for a slice of bytes.
@@ -86,17 +87,17 @@ func (t *MutableTransformer) Set(transformer Transformer) {
t.lock.Unlock()
}
func (t *MutableTransformer) TransformFromStorage(data []byte, context Context) (out []byte, stale bool, err error) {
func (t *MutableTransformer) TransformFromStorage(ctx context.Context, data []byte, dataCtx Context) (out []byte, stale bool, err error) {
t.lock.RLock()
transformer := t.transformer
t.lock.RUnlock()
return transformer.TransformFromStorage(data, context)
return transformer.TransformFromStorage(ctx, data, dataCtx)
}
func (t *MutableTransformer) TransformToStorage(data []byte, context Context) (out []byte, err error) {
func (t *MutableTransformer) TransformToStorage(ctx context.Context, data []byte, dataCtx Context) (out []byte, err error) {
t.lock.RLock()
transformer := t.transformer
t.lock.RUnlock()
return transformer.TransformToStorage(data, context)
return transformer.TransformToStorage(ctx, data, dataCtx)
}
// PrefixTransformer holds a transformer interface and the prefix that the transformation is located under.
@@ -129,12 +130,12 @@ func NewPrefixTransformers(err error, transformers ...PrefixTransformer) Transfo
// TransformFromStorage finds the first transformer with a prefix matching the provided data and returns
// the result of transforming the value. It will always mark any transformation as stale that is not using
// the first transformer.
func (t *prefixTransformers) TransformFromStorage(data []byte, context Context) ([]byte, bool, error) {
func (t *prefixTransformers) TransformFromStorage(ctx context.Context, data []byte, dataCtx Context) ([]byte, bool, error) {
start := time.Now()
var errs []error
for i, transformer := range t.transformers {
if bytes.HasPrefix(data, transformer.Prefix) {
result, stale, err := transformer.Transformer.TransformFromStorage(data[len(transformer.Prefix):], context)
result, stale, err := transformer.Transformer.TransformFromStorage(ctx, data[len(transformer.Prefix):], dataCtx)
// To migrate away from encryption, user can specify an identity transformer higher up
// (in the config file) than the encryption transformer. In that scenario, the identity transformer needs to
// identify (during reads from disk) whether the data being read is encrypted or not. If the data is encrypted,
@@ -194,12 +195,12 @@ func (t *prefixTransformers) TransformFromStorage(data []byte, context Context)
}
// TransformToStorage uses the first transformer and adds its prefix to the data.
func (t *prefixTransformers) TransformToStorage(data []byte, context Context) ([]byte, error) {
func (t *prefixTransformers) TransformToStorage(ctx context.Context, data []byte, dataCtx Context) ([]byte, error) {
start := time.Now()
transformer := t.transformers[0]
prefixedData := make([]byte, len(transformer.Prefix), len(data)+len(transformer.Prefix))
copy(prefixedData, transformer.Prefix)
result, err := transformer.Transformer.TransformToStorage(data, context)
result, err := transformer.Transformer.TransformToStorage(ctx, data, dataCtx)
RecordTransformation("to_storage", string(transformer.Prefix), start, err)
if err != nil {
return nil, err