removing cloudkms secret store #495 (#496)

This commit is contained in:
Carlos Mendible 2020-10-14 01:16:45 +02:00 committed by GitHub
parent 182d204111
commit 2ae711d3e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 0 additions and 194 deletions

View File

@ -1,150 +0,0 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
package cloudkms
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
cloudkms "cloud.google.com/go/kms/apiv1"
"cloud.google.com/go/storage"
"github.com/dapr/components-contrib/secretstores"
"github.com/dapr/dapr/pkg/logger"
"google.golang.org/api/option"
kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
)
// cloudkmsSecretStore is a secret store implementation of GCS KMS
type cloudkmsSecretStore struct {
cloudkmsclient *cloudkms.KeyManagementClient
storageclient *storage.Client
metadata *cloudkmsMetadata
logger logger.Logger
}
type cloudkmsMetadata struct {
Type string `json:"type"`
ProjectID string `json:"project_id"`
PrivateKeyID string `json:"private_key_id"`
PrivateKey string `json:"private_key"`
ClientEmail string `json:"client_email"`
ClientID string `json:"client_id"`
AuthURI string `json:"auth_uri"`
TokenURI string `json:"token_uri"`
AuthProviderCertURL string `json:"auth_provider_x509_cert_url"`
ClientCertURL string `json:"client_x509_cert_url"`
GCPStorageBucket string `json:"gcp_storage_bucket"`
SecretObject string `json:"secret_object"`
KeyRingID string `json:"key_ring_id"`
CryptoKeyID string `json:"crypto_key_id"`
}
// NewCloudKMSSecretStore returns a new cloudkmsSecretStore instance
func NewCloudKMSSecretStore(logger logger.Logger) secretstores.SecretStore {
return &cloudkmsSecretStore{logger: logger}
}
// Init creates a cloudkmsClient
func (c *cloudkmsSecretStore) Init(metadata secretstores.Metadata) error {
b, err := c.parseMetadata(metadata)
if err != nil {
return err
}
var cloudkmsMeta cloudkmsMetadata
err = json.Unmarshal(b, &cloudkmsMeta)
if err != nil {
return err
}
clientOptions := option.WithCredentialsJSON(b)
ctx := context.Background()
cloudkmsClient, err := cloudkms.NewKeyManagementClient(ctx, clientOptions)
if err != nil {
return fmt.Errorf("error creating cloudkms client: %s", err)
}
storageClient, err := storage.NewClient(ctx, clientOptions)
if err != nil {
return fmt.Errorf("error creating cloud storage client: %s", err)
}
c.cloudkmsclient = cloudkmsClient
c.storageclient = storageClient
c.metadata = &cloudkmsMeta
return nil
}
// GetSecret retrieves a secret using a key and returns a map of decrypted string
func (c *cloudkmsSecretStore) GetSecret(req secretstores.GetSecretRequest) (secretstores.GetSecretResponse, error) {
gcpStorageBucket := c.metadata.GCPStorageBucket
secretObject := c.metadata.SecretObject
ciphertext, err := c.getCipherTextFromSecretObject(gcpStorageBucket, secretObject)
if err != nil {
return secretstores.GetSecretResponse{Data: nil}, fmt.Errorf("error reading secret file: %s", err)
}
name := fmt.Sprintf("projects/%s/locations/global/keyRings/%s/cryptoKeys/%s",
c.metadata.ProjectID, c.metadata.KeyRingID, c.metadata.CryptoKeyID)
secretResp, err := c.decryptSymmetric(name, ciphertext)
secretValue := string(secretResp)
if err != nil {
return secretstores.GetSecretResponse{Data: nil}, fmt.Errorf("error occurred while decrypting: %s", err)
}
return secretstores.GetSecretResponse{
Data: map[string]string{
secretstores.DefaultSecretRefKeyName: secretValue,
},
}, nil
}
func (c *cloudkmsSecretStore) getCipherTextFromSecretObject(gcpStorageBucket string, secretObject string) ([]byte, error) {
ctx := context.Background()
client := c.storageclient
rc, err := client.Bucket(gcpStorageBucket).Object(secretObject).NewReader(ctx)
if err != nil {
return nil, fmt.Errorf("creation of read client failed: %s", err)
}
defer rc.Close()
data, err := ioutil.ReadAll(rc)
if err != nil {
return nil, fmt.Errorf("failed while reading secret file: %s", err)
}
return data, nil
}
func (c *cloudkmsSecretStore) decryptSymmetric(name string, ciphertext []byte) ([]byte, error) {
ctx := context.Background()
// Build the request
req := &kmspb.DecryptRequest{
Name: name,
Ciphertext: ciphertext,
}
resp, err := c.cloudkmsclient.Decrypt(ctx, req)
if err != nil {
return nil, fmt.Errorf("decrypt: %v", err)
}
return resp.Plaintext, nil
}
func (c *cloudkmsSecretStore) parseMetadata(metadata secretstores.Metadata) ([]byte, error) {
b, err := json.Marshal(metadata.Properties)
return b, err
}

View File

@ -1,44 +0,0 @@
package cloudkms
import (
"fmt"
"testing"
"github.com/dapr/components-contrib/secretstores"
"github.com/dapr/dapr/pkg/logger"
"github.com/stretchr/testify/assert"
)
func TestInit(t *testing.T) {
m := secretstores.Metadata{}
s := NewCloudKMSSecretStore(logger.NewLogger("test"))
t.Run("Init with valid metadata", func(t *testing.T) {
m.Properties = map[string]string{
"type": "service_account",
"project_id": "a",
"private_key_id": "a",
"private_key": "a",
"client_email": "a",
"client_id": "a",
"auth_uri": "a",
"token_uri": "a",
"auth_provider_x509_cert_url": "a",
"client_x509_cert_url": "a",
"secret_object": "a",
"gcp_storage_bucket": "a",
"key_ring_id": "a",
"crypto_key_id": "a",
}
err := s.Init(m)
assert.Nil(t, err)
})
t.Run("Init with missing metadata", func(t *testing.T) {
m.Properties = map[string]string{
"dummy": "a",
}
err := s.Init(m)
assert.NotNil(t, err)
assert.Equal(t, err, fmt.Errorf("error creating cloudkms client: missing 'type' field in credentials"))
})
}