Allow kube-apiserver to test the status of kms-plugin.

This commit is contained in:
immutablet
2019-05-30 11:15:35 -07:00
parent 49c34bb597
commit 05fdbb201f
15 changed files with 565 additions and 105 deletions

View File

@@ -23,8 +23,11 @@ import (
"encoding/base64"
"fmt"
"net"
"sync"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
kmsapi "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v1beta1"
"k8s.io/klog"
@@ -32,33 +35,32 @@ import (
const (
kmsAPIVersion = "v1beta1"
sockFile = "@kms-provider.sock"
unixProtocol = "unix"
)
// base64Plugin gRPC sever for a mock KMS provider.
// Uses base64 to simulate encrypt and decrypt.
type base64Plugin struct {
grpcServer *grpc.Server
listener net.Listener
// Allow users of the plugin to sense requests that were passed to KMS.
encryptRequest chan *kmsapi.EncryptRequest
grpcServer *grpc.Server
listener net.Listener
mu *sync.Mutex
lastEncryptRequest *kmsapi.EncryptRequest
inFailedState bool
}
func newBase64Plugin() (*base64Plugin, error) {
listener, err := net.Listen(unixProtocol, sockFile)
func newBase64Plugin(socketPath string) (*base64Plugin, error) {
listener, err := net.Listen(unixProtocol, socketPath)
if err != nil {
return nil, fmt.Errorf("failed to listen on the unix socket, error: %v", err)
}
klog.Infof("Listening on %s", sockFile)
klog.Infof("Listening on %s", socketPath)
server := grpc.NewServer()
result := &base64Plugin{
grpcServer: server,
listener: listener,
encryptRequest: make(chan *kmsapi.EncryptRequest, 1),
grpcServer: server,
listener: listener,
mu: &sync.Mutex{},
}
kmsapi.RegisterKeyManagementServiceServer(server, result)
@@ -73,6 +75,18 @@ func (s *base64Plugin) cleanUp() {
var testProviderAPIVersion = kmsAPIVersion
func (s *base64Plugin) enterFailedState() {
s.mu.Lock()
defer s.mu.Unlock()
s.inFailedState = true
}
func (s *base64Plugin) exitFailedState() {
s.mu.Lock()
defer s.mu.Unlock()
s.inFailedState = false
}
func (s *base64Plugin) Version(ctx context.Context, request *kmsapi.VersionRequest) (*kmsapi.VersionResponse, error) {
return &kmsapi.VersionResponse{Version: testProviderAPIVersion, RuntimeName: "testKMS", RuntimeVersion: "0.0.1"}, nil
}
@@ -80,6 +94,12 @@ func (s *base64Plugin) Version(ctx context.Context, request *kmsapi.VersionReque
func (s *base64Plugin) Decrypt(ctx context.Context, request *kmsapi.DecryptRequest) (*kmsapi.DecryptResponse, error) {
klog.Infof("Received Decrypt Request for DEK: %s", string(request.Cipher))
s.mu.Lock()
defer s.mu.Unlock()
if s.inFailedState {
return nil, status.Error(codes.FailedPrecondition, "failed precondition - key disabled")
}
buf := make([]byte, base64.StdEncoding.DecodedLen(len(request.Cipher)))
n, err := base64.StdEncoding.Decode(buf, request.Cipher)
if err != nil {
@@ -91,7 +111,13 @@ func (s *base64Plugin) Decrypt(ctx context.Context, request *kmsapi.DecryptReque
func (s *base64Plugin) Encrypt(ctx context.Context, request *kmsapi.EncryptRequest) (*kmsapi.EncryptResponse, error) {
klog.Infof("Received Encrypt Request for DEK: %x", request.Plain)
s.encryptRequest <- request
s.mu.Lock()
defer s.mu.Unlock()
s.lastEncryptRequest = request
if s.inFailedState {
return nil, status.Error(codes.FailedPrecondition, "failed precondition - key disabled")
}
buf := make([]byte, base64.StdEncoding.EncodedLen(len(request.Plain)))
base64.StdEncoding.Encode(buf, request.Plain)