Skip to content

Commit

Permalink
Adds conformance tests for AWS Secrets store component (#3588)
Browse files Browse the repository at this point in the history
Signed-off-by: Elena Kolevska <[email protected]>
Co-authored-by: Yaron Schneider <[email protected]>
  • Loading branch information
elena-kolevska and yaron2 authored Nov 8, 2024
1 parent 9833e56 commit b05e19a
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 6 deletions.
15 changes: 15 additions & 0 deletions .github/infrastructure/docker-compose-secrets-manager.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: "3.8"

services:
localstack:
container_name: "conformance-aws-secrets-manager"
image: localstack/localstack
ports:
- "127.0.0.1:4566:4566"
environment:
- DEBUG=1
- DOCKER_HOST=unix:///var/run/docker.sock
volumes:
- "${PWD}/.github/scripts/docker-compose-init/init-conformance-state-aws-secrets-manager.sh:/etc/localstack/init/ready.d/init-aws.sh" # ready hook
- "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
terraform {
required_version = ">=0.13"

required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}

variable "TIMESTAMP" {
type = string
description = "Timestamp of the GitHub workflow run."
}

variable "UNIQUE_ID" {
type = string
description = "Unique ID of the GitHub workflow run."
}

provider "aws" {
region = "us-east-1"
default_tags {
tags = {
Purpose = "AutomatedConformanceTesting"
Timestamp = "${var.TIMESTAMP}"
}
}
}

# Create the first secret in AWS Secrets Manager
resource "aws_secretsmanager_secret" "conftestsecret" {
name = "conftestsecret"
description = "Secret for conformance test"
recovery_window_in_days = 0
}

resource "aws_secretsmanager_secret_version" "conftestsecret_value" {
secret_id = aws_secretsmanager_secret.conftestsecret.id
secret_string = "abcd"
}

# Create the second secret in AWS Secrets Manager
resource "aws_secretsmanager_secret" "secondsecret" {
name = "secondsecret"
description = "Another secret for conformance test"
recovery_window_in_days = 0
}

resource "aws_secretsmanager_secret_version" "secondsecret_value" {
secret_id = aws_secretsmanager_secret.secondsecret.id
secret_string = "efgh"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh

set +e

# Navigate to the Terraform directory
cd ".github/infrastructure/terraform/conformance/secretstores/aws/secretsmanager"

# Run Terraform
terraform destroy -auto-approve -var="UNIQUE_ID=$UNIQUE_ID" -var="TIMESTAMP=$CURRENT_TIME"
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh

set -e

# Set variables for GitHub Actions
echo "AWS_REGION=us-east-1" >> $GITHUB_ENV

# Navigate to the Terraform directory
cd ".github/infrastructure/terraform/conformance/secretstores/aws/secretsmanager"

# Run Terraform
terraform init
terraform validate -no-color
terraform plan -no-color -var="UNIQUE_ID=$UNIQUE_ID" -var="TIMESTAMP=$CURRENT_TIME"
terraform apply -auto-approve -var="UNIQUE_ID=$UNIQUE_ID" -var="TIMESTAMP=$CURRENT_TIME"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

awslocal secretsmanager create-secret \
--name conftestsecret \
--secret-string "abcd"

awslocal secretsmanager create-secret \
--name secondsecret \
--secret-string "efgh"
11 changes: 11 additions & 0 deletions .github/scripts/test-info.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,17 @@ const components = {
conformance: true,
certification: true,
},
'secretstores.aws.secretsmanager.terraform': {
conformance: true,
requireAWSCredentials: true,
requireTerraform: true,
conformanceSetup: 'conformance-secretstores.aws.secretsmanager.secretsmanager-setup.sh',
conformanceDestroy: 'conformance-secretstores.aws.secretsmanager.secretsmanager-destroy.sh',
},
'secretstores.aws.secretsmanager.docker': {
conformance: true,
conformanceSetup: 'docker-compose.sh secrets-manager',
},
'state.aws.dynamodb': {
certification: true,
requireAWSCredentials: true,
Expand Down
19 changes: 19 additions & 0 deletions secretstores/aws/secretmanager/metadata.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# yaml-language-server: $schema=../../../component-metadata-schema.json
schemaVersion: v1
type: secretstores
name: aws.secretsmanager
version: v1
status: beta
title: "AWS Secrets manager"
urls:
- title: Reference
url: https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/
builtinAuthenticationProfiles:
- name: "aws"
metadata:
- name: endpoint
required: false
description: |
The Secrets manager endpoint. The AWS SDK will generate a default endpoint if not specified. Useful for local testing with AWS LocalStack
example: '"http://localhost:4566"'
type: string
11 changes: 6 additions & 5 deletions secretstores/aws/secretmanager/secretmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ func NewSecretManager(logger logger.Logger) secretstores.SecretStore {
}

type SecretManagerMetaData struct {
Region string `json:"region"`
AccessKey string `json:"accessKey"`
SecretKey string `json:"secretKey"`
SessionToken string `json:"sessionToken"`
Region string `json:"region" mapstructure:"region" mdignore:"true"`
AccessKey string `json:"accessKey" mapstructure:"accessKey" mdignore:"true"`
SecretKey string `json:"secretKey" mapstructure:"secretKey" mdignore:"true"`
SessionToken string `json:"sessionToken" mapstructure:"sessionToken" mdignore:"true"`
Endpoint string `json:"endpoint" mapstructure:"endpoint"`
}

type smSecretStore struct {
Expand Down Expand Up @@ -136,7 +137,7 @@ func (s *smSecretStore) BulkGetSecret(ctx context.Context, req secretstores.Bulk
}

func (s *smSecretStore) getClient(metadata *SecretManagerMetaData) (*secretsmanager.SecretsManager, error) {
sess, err := awsAuth.GetClient(metadata.AccessKey, metadata.SecretKey, metadata.SessionToken, metadata.Region, "")
sess, err := awsAuth.GetClient(metadata.AccessKey, metadata.SecretKey, metadata.SessionToken, metadata.Region, metadata.Endpoint)
if err != nil {
return nil, err
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: awssecretmanager
spec:
type: secretstores.aws.secretmanager
version: v1
metadata:
- name: endpoint
value: "http://localhost:4566" # AWS LocalStack address
- name: accessKey
value: "test" # AWS LocalStack placeholder
- name: secretKey
value: "test" # AWS LocalStack placeholder
- name: region
value: "us-east-1" # AWS LocalStack placeholder
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: awssecretmanager
namespace: default
spec:
type: secretstores.aws.secretmanager
version: v1
metadata:
- name: accessKey
value: ${{AWS_ACCESS_KEY_ID}}
- name: secretKey
value: ${{AWS_SECRET_ACCESS_KEY}}
- name: region
value: ${{AWS_REGION}}
4 changes: 4 additions & 0 deletions tests/config/secretstores/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ components:
operations: []
- component: local.file
operations: []
- component: aws.secretsmanager.docker
operations: []
- component: aws.secretsmanager.terraform
operations: []
- component: azure.keyvault.certificate
operations: []
- component: azure.keyvault.serviceprincipal
Expand Down
2 changes: 1 addition & 1 deletion tests/conformance/secretstores/secretstores.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func ConformanceTests(t *testing.T, props map[string]string, store secretstores.

t.Run("ping", func(t *testing.T) {
err := secretstores.Ping(context.Background(), store)
// TODO: Ideally, all stable components should implenment ping function,
// TODO: Ideally, all stable components should implement a ping function,
// so will only assert require.NoError(t, err) finally, i.e. when current implementation
// implements ping in existing stable components
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions tests/conformance/secretstores_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/dapr/components-contrib/secretstores"
ss_aws "github.com/dapr/components-contrib/secretstores/aws/secretmanager"
ss_azure "github.com/dapr/components-contrib/secretstores/azure/keyvault"
ss_hashicorp_vault "github.com/dapr/components-contrib/secretstores/hashicorp/vault"
ss_kubernetes "github.com/dapr/components-contrib/secretstores/kubernetes"
Expand Down Expand Up @@ -71,6 +72,10 @@ func loadSecretStore(name string) secretstores.SecretStore {
return ss_local_file.NewLocalSecretStore(testLogger)
case "hashicorp.vault":
return ss_hashicorp_vault.NewHashiCorpVaultSecretStore(testLogger)
case "aws.secretsmanager.docker":
return ss_aws.NewSecretManager(testLogger)
case "aws.secretsmanager.terraform":
return ss_aws.NewSecretManager(testLogger)
default:
return nil
}
Expand Down

0 comments on commit b05e19a

Please sign in to comment.