From bcb5d263e8b7e5d752b5b4f10e5fd3015db61549 Mon Sep 17 00:00:00 2001 From: Mykhailo Sizov Date: Thu, 2 May 2024 14:35:07 +0300 Subject: [PATCH] feat: delete key from aws kms Signed-off-by: Mykhailo Sizov --- pkg/kms/aws/service.go | 15 ++++++ pkg/kms/aws/service_mocks.go | 20 +++++++ pkg/kms/aws/service_test.go | 53 +++++++++++++++++++ .../issuecredential_service.go | 2 +- 4 files changed, 89 insertions(+), 1 deletion(-) diff --git a/pkg/kms/aws/service.go b/pkg/kms/aws/service.go index e84616cc0..1d947b978 100644 --- a/pkg/kms/aws/service.go +++ b/pkg/kms/aws/service.go @@ -42,6 +42,7 @@ type awsClient interface { optFns ...func(*kms.Options)) (*kms.CreateAliasOutput, error) Encrypt(ctx context.Context, params *kms.EncryptInput, optFns ...func(*kms.Options)) (*kms.EncryptOutput, error) Decrypt(ctx context.Context, params *kms.DecryptInput, optFns ...func(*kms.Options)) (*kms.DecryptOutput, error) + ScheduleKeyDeletion(ctx context.Context, params *kms.ScheduleKeyDeletionInput, optFns ...func(*kms.Options)) (*kms.ScheduleKeyDeletionOutput, error) } type metricsProvider interface { @@ -393,6 +394,20 @@ func (s *Service) CreateAndExportPubKeyBytes(kt arieskms.KeyType, _ ...arieskms. return keyID, pubKeyBytes, nil } +// Remove removes kms key referenced by keyURI from KMS. +func (s *Service) Remove(keyURI string) error { + keyID, err := s.getKeyID(keyURI) + if err != nil { + return err + } + + _, err = s.client.ScheduleKeyDeletion(context.Background(), &kms.ScheduleKeyDeletionInput{ + KeyId: aws.String(keyID), + }) + + return err +} + // ImportPrivateKey private key. func (s *Service) ImportPrivateKey(_ interface{}, _ arieskms.KeyType, _ ...arieskms.PrivateKeyOpts) (string, interface{}, error) { diff --git a/pkg/kms/aws/service_mocks.go b/pkg/kms/aws/service_mocks.go index ac8806377..3973e662b 100644 --- a/pkg/kms/aws/service_mocks.go +++ b/pkg/kms/aws/service_mocks.go @@ -156,6 +156,26 @@ func (mr *MockawsClientMockRecorder) GetPublicKey(ctx, params interface{}, optFn return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPublicKey", reflect.TypeOf((*MockawsClient)(nil).GetPublicKey), varargs...) } +// ScheduleKeyDeletion mocks base method. +func (m *MockawsClient) ScheduleKeyDeletion(ctx context.Context, params *kms.ScheduleKeyDeletionInput, optFns ...func(*kms.Options)) (*kms.ScheduleKeyDeletionOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, params} + for _, a := range optFns { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ScheduleKeyDeletion", varargs...) + ret0, _ := ret[0].(*kms.ScheduleKeyDeletionOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ScheduleKeyDeletion indicates an expected call of ScheduleKeyDeletion. +func (mr *MockawsClientMockRecorder) ScheduleKeyDeletion(ctx, params interface{}, optFns ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, params}, optFns...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScheduleKeyDeletion", reflect.TypeOf((*MockawsClient)(nil).ScheduleKeyDeletion), varargs...) +} + // Sign mocks base method. func (m *MockawsClient) Sign(ctx context.Context, params *kms.SignInput, optFns ...func(*kms.Options)) (*kms.SignOutput, error) { m.ctrl.T.Helper() diff --git a/pkg/kms/aws/service_test.go b/pkg/kms/aws/service_test.go index ab1353bf2..6173377a6 100644 --- a/pkg/kms/aws/service_test.go +++ b/pkg/kms/aws/service_test.go @@ -396,6 +396,59 @@ func TestCreate(t *testing.T) { }) } +func TestRemove(t *testing.T) { + awsConfig := &aws.Config{ + Region: "ca", + } + + t.Run("success", func(t *testing.T) { + ctr := gomock.NewController(t) + + metric := NewMockmetricsProvider(ctr) + client := NewMockawsClient(ctr) + + keyURI := "aws-kms://arn:aws:kms:ca-central-1:111122223333:key/800d5768-3fd7-4edd-a4b8-4c81c3e4c147" + expectedKeyID := "800d5768-3fd7-4edd-a4b8-4c81c3e4c147" + + client.EXPECT().ScheduleKeyDeletion(gomock.Any(), &kms.ScheduleKeyDeletionInput{KeyId: &expectedKeyID}). + Return(nil, nil) + + svc := New(awsConfig, metric, "", WithAWSClient(client)) + + err := svc.Remove(keyURI) + require.NoError(t, err) + }) + + t.Run("failed to parse key id", func(t *testing.T) { + metric := NewMockmetricsProvider(gomock.NewController(t)) + + svc := New(awsConfig, metric, "", []Opts{}...) + + err := svc.Remove("aws-kms://arn:aws:kms:key1") + require.Error(t, err) + require.Contains(t, err.Error(), "extracting key id from URI failed") + }) + + t.Run("failed to schedule key deletion", func(t *testing.T) { + ctr := gomock.NewController(t) + + metric := NewMockmetricsProvider(ctr) + client := NewMockawsClient(ctr) + + keyURI := "aws-kms://arn:aws:kms:ca-central-1:111122223333:key/800d5768-3fd7-4edd-a4b8-4c81c3e4c147" + expectedKeyID := "800d5768-3fd7-4edd-a4b8-4c81c3e4c147" + + client.EXPECT().ScheduleKeyDeletion(gomock.Any(), &kms.ScheduleKeyDeletionInput{KeyId: &expectedKeyID}). + Return(nil, errors.New("some error")) + + svc := New(awsConfig, metric, "", WithAWSClient(client)) + + err := svc.Remove(keyURI) + require.Error(t, err) + require.Contains(t, err.Error(), "some error") + }) +} + func TestGet(t *testing.T) { awsConfig := aws.Config{ Region: "ca", diff --git a/pkg/service/issuecredential/issuecredential_service.go b/pkg/service/issuecredential/issuecredential_service.go index fc57de56a..e7cab065a 100644 --- a/pkg/service/issuecredential/issuecredential_service.go +++ b/pkg/service/issuecredential/issuecredential_service.go @@ -113,7 +113,7 @@ func (s *Service) IssueCredential( f(options) } - kms, err := s.kmsRegistry.GetKeyManager(profile.KMSConfig) + kms, err := s.kmsRegistry.GetKeyManager(profile.KMSConfig) // If nil - default config is used. if err != nil { return nil, fmt.Errorf("get kms: %w", err) }