From af8eb3efca67b40c078389e8299b27263179ce79 Mon Sep 17 00:00:00 2001 From: Danny Schofield Date: Thu, 2 May 2024 17:39:27 -0400 Subject: [PATCH] end2end: include test with cdk provisioning --- tests/cdk/dynamo/README.md | 12 ++++++ tests/cdk/dynamo/cdk.json | 64 +++++++++++++++++++++++++++ tests/cdk/dynamo/dyanmo_test.go | 26 +++++++++++ tests/cdk/dynamo/dynamo.go | 76 +++++++++++++++++++++++++++++++++ tests/cdk/dynamo/go.mod | 26 +++++++++++ tests/cdk/dynamo/go.sum | 53 +++++++++++++++++++++++ tests/end2end_test.go | 66 +++++++++++++++++++++++++++- 7 files changed, 322 insertions(+), 1 deletion(-) create mode 100644 tests/cdk/dynamo/README.md create mode 100644 tests/cdk/dynamo/cdk.json create mode 100644 tests/cdk/dynamo/dyanmo_test.go create mode 100644 tests/cdk/dynamo/dynamo.go create mode 100644 tests/cdk/dynamo/go.mod create mode 100644 tests/cdk/dynamo/go.sum diff --git a/tests/cdk/dynamo/README.md b/tests/cdk/dynamo/README.md new file mode 100644 index 0000000..79e5c45 --- /dev/null +++ b/tests/cdk/dynamo/README.md @@ -0,0 +1,12 @@ +# Welcome to your CDK Go project! + +This is a blank project for CDK development with Go. + +The `cdk.json` file tells the CDK toolkit how to execute your app. + +## Useful commands + + * `cdk deploy` deploy this stack to your default AWS account/region + * `cdk diff` compare deployed stack with current state + * `cdk synth` emits the synthesized CloudFormation template + * `go test` run unit tests diff --git a/tests/cdk/dynamo/cdk.json b/tests/cdk/dynamo/cdk.json new file mode 100644 index 0000000..fa640e7 --- /dev/null +++ b/tests/cdk/dynamo/cdk.json @@ -0,0 +1,64 @@ +{ + "app": "go mod download && go run dynamo.go", + "watch": { + "include": [ + "**" + ], + "exclude": [ + "README.md", + "cdk*.json", + "go.mod", + "go.sum", + "**/*test.go" + ] + }, + "context": { + "@aws-cdk/aws-lambda:recognizeLayerVersion": true, + "@aws-cdk/core:checkSecretUsage": true, + "@aws-cdk/core:target-partitions": [ + "aws", + "aws-cn" + ], + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, + "@aws-cdk/aws-iam:minimizePolicies": true, + "@aws-cdk/core:validateSnapshotRemovalPolicy": true, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, + "@aws-cdk/core:enablePartitionLiterals": true, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, + "@aws-cdk/aws-iam:standardizedServicePrincipals": true, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, + "@aws-cdk/aws-route53-patters:useCertificate": true, + "@aws-cdk/customresources:installLatestAwsSdkDefault": false, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, + "@aws-cdk/aws-redshift:columnId": true, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, + "@aws-cdk/aws-kms:aliasNameRef": true, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, + "@aws-cdk/aws-efs:denyAnonymousAccess": true, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true, + "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true, + "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true, + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true + } +} \ No newline at end of file diff --git a/tests/cdk/dynamo/dyanmo_test.go b/tests/cdk/dynamo/dyanmo_test.go new file mode 100644 index 0000000..5ea34a7 --- /dev/null +++ b/tests/cdk/dynamo/dyanmo_test.go @@ -0,0 +1,26 @@ +package main + +// import ( +// "testing" + +// "github.com/aws/aws-cdk-go/awscdk/v2" +// "github.com/aws/aws-cdk-go/awscdk/v2/assertions" +// "github.com/aws/jsii-runtime-go" +// ) + +// example tests. To run these tests, uncomment this file along with the +// example resource in dynamo_test.go +// func TestSqsStack(t *testing.T) { +// // GIVEN +// app := awscdk.NewApp(nil) + +// // WHEN +// stack := NewSqsStack(app, "MyStack", nil) + +// // THEN +// template := assertions.Template_FromStack(stack, nil) + +// template.HasResourceProperties(jsii.String("AWS::SQS::Queue"), map[string]interface{}{ +// "VisibilityTimeout": 300, +// }) +// } diff --git a/tests/cdk/dynamo/dynamo.go b/tests/cdk/dynamo/dynamo.go new file mode 100644 index 0000000..d316039 --- /dev/null +++ b/tests/cdk/dynamo/dynamo.go @@ -0,0 +1,76 @@ +package main + +import ( + "github.com/aws/aws-cdk-go/awscdk/v2" + "github.com/aws/aws-cdk-go/awscdk/v2/awsdynamodb" + + "github.com/aws/constructs-go/constructs/v10" + "github.com/aws/jsii-runtime-go" +) + +type DynamoStackProps struct { + awscdk.StackProps +} + +func NewDynamoStack(scope constructs.Construct, id string, props *DynamoStackProps) awscdk.Stack { + var sprops awscdk.StackProps + if props != nil { + sprops = props.StackProps + } + stack := awscdk.NewStack(scope, &id, &sprops) + + // The code that defines your stack goes here + + // example resource + name := "cdktesttable" + awsdynamodb.NewTable(stack, jsii.String("Table"), &awsdynamodb.TableProps{ + TableName: &name, + PartitionKey: &awsdynamodb.Attribute{ + Name: jsii.String("pk"), + Type: awsdynamodb.AttributeType_STRING, + }, + }) + + return stack +} + +func main() { + defer jsii.Close() + + app := awscdk.NewApp(nil) + + NewDynamoStack(app, "DynamoStack", &DynamoStackProps{ + awscdk.StackProps{ + Env: env(), + }, + }) + + app.Synth(nil) +} + +// env determines the AWS environment (account+region) in which our stack is to +// be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html +func env() *awscdk.Environment { + // If unspecified, this stack will be "environment-agnostic". + // Account/Region-dependent features and context lookups will not work, but a + // single synthesized template can be deployed anywhere. + //--------------------------------------------------------------------------- + return nil + + // Uncomment if you know exactly what account and region you want to deploy + // the stack to. This is the recommendation for production stacks. + //--------------------------------------------------------------------------- + // return &awscdk.Environment{ + // Account: jsii.String("123456789012"), + // Region: jsii.String("us-east-1"), + // } + + // Uncomment to specialize this stack for the AWS Account and Region that are + // implied by the current CLI configuration. This is recommended for dev + // stacks. + //--------------------------------------------------------------------------- + // return &awscdk.Environment{ + // Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")), + // Region: jsii.String(os.Getenv("CDK_DEFAULT_REGION")), + // } +} diff --git a/tests/cdk/dynamo/go.mod b/tests/cdk/dynamo/go.mod new file mode 100644 index 0000000..6a59004 --- /dev/null +++ b/tests/cdk/dynamo/go.mod @@ -0,0 +1,26 @@ +module dynamo + +go 1.18 + +require ( + github.com/aws/aws-cdk-go/awscdk v1.204.0-devpreview + github.com/aws/aws-cdk-go/awscdk/v2 v2.135.0 + github.com/aws/constructs-go/constructs/v10 v10.3.0 + github.com/aws/jsii-runtime-go v1.96.0 +) + +require ( + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/aws/constructs-go/constructs/v3 v3.4.232 // indirect + github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.202 // indirect + github.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.2 // indirect + github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv6/v2 v2.0.1 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/yuin/goldmark v1.4.13 // indirect + golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect + golang.org/x/mod v0.16.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/tools v0.19.0 // indirect +) diff --git a/tests/cdk/dynamo/go.sum b/tests/cdk/dynamo/go.sum new file mode 100644 index 0000000..b5414d6 --- /dev/null +++ b/tests/cdk/dynamo/go.sum @@ -0,0 +1,53 @@ +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/aws/aws-cdk-go/awscdk v1.204.0-devpreview h1:t3TI4mtmRQlUF5OceL3zhhTlz1RtFMMbsWQ1oMrAsWg= +github.com/aws/aws-cdk-go/awscdk v1.204.0-devpreview/go.mod h1:ZAyiU+hVHfDS6Vvxf1ljmwawmA5Ri6FUay6M04+93pk= +github.com/aws/aws-cdk-go/awscdk/v2 v2.135.0 h1:Ld+XZJTzKyW0SwML+9F9Cdqyg+30Rt6d4A5YMgCp1BE= +github.com/aws/aws-cdk-go/awscdk/v2 v2.135.0/go.mod h1:Uk4vqgQ2uInmANDjyYBQEjtSXJvCOfFdHftZrnH963A= +github.com/aws/constructs-go/constructs/v10 v10.3.0 h1:LsjBIMiaDX/vqrXWhzTquBJ9pPdi02/H+z1DCwg0PEM= +github.com/aws/constructs-go/constructs/v10 v10.3.0/go.mod h1:GgzwIwoRJ2UYsr3SU+JhAl+gq5j39bEMYf8ev3J+s9s= +github.com/aws/constructs-go/constructs/v3 v3.4.232 h1:YLw1wSu8/qqmacsZWPXI+qFNu4ml2YZwtRZHL2gaB8M= +github.com/aws/constructs-go/constructs/v3 v3.4.232/go.mod h1:ejR5Hd2llgfqo68taM7H/hnri4hrHObbsqbT6YySLMI= +github.com/aws/jsii-runtime-go v1.96.0 h1:ma4ee4CgkNT/OnEsnXVQQPUCwvx+3p4SYaJ9qmnZpWg= +github.com/aws/jsii-runtime-go v1.96.0/go.mod h1:ISVfzRvqqxXAYyPKhucPCFeUjIjnqtj9QzE/77yk9pQ= +github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.202 h1:VixXB9DnHN8oP7pXipq8GVFPjWCOdeNxIaS/ZyUwTkI= +github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.202/go.mod h1:iPUti/SWjA3XAS3CpnLciFjS8TN9Y+8mdZgDfSgcyus= +github.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.2 h1:k+WD+6cERd59Mao84v0QtRrcdZuuSMfzlEmuIypKnVs= +github.com/cdklabs/awscdk-asset-kubectl-go/kubectlv20/v2 v2.1.2/go.mod h1:CvFHBo0qcg8LUkJqIxQtP1rD/sNGv9bX3L2vHT2FUAo= +github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv6/v2 v2.0.1 h1:MBBQNKKPJ5GArbctgwpiCy7KmwGjHDjUUH5wEzwIq8w= +github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv6/v2 v2.0.1/go.mod h1:/2WiXEft9s8ViJjD01CJqDuyJ8HXBjhBLtK5OvJfdSc= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= +golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= +golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/tests/end2end_test.go b/tests/end2end_test.go index 59d0ecd..f901274 100644 --- a/tests/end2end_test.go +++ b/tests/end2end_test.go @@ -917,6 +917,71 @@ Organization: }, Targets: []string{"stacks"}, }, + { + Name: "CDK example", + OrgYaml: ` +Organization: + Name: root + Accounts: + - AccountName: master + Email: master@example.com + Stacks: + - Type: CDK + Path: cdk/dynamo +`, + FetchExpected: &resource.OrganizationUnit{ + OUName: "root", + Accounts: []*resource.Account{ + { + AccountName: "master", + Email: "master@example.com", + ManagementAccount: true, + }, + }, + }, + ParseExpected: &resource.OrganizationUnit{ + OUName: "root", + ChildOUs: []*resource.OrganizationUnit{}, + Accounts: []*resource.Account{ + { + AccountName: "master", + Email: "master@example.com", + ManagementAccount: true, + BaselineStacks: []resource.Stack{ + { + Type: "CDK", + Path: "cdk/dynamo", + // Region: "us-west-2", + }, + }, + }, + }, + }, + ExpectedResources: func(t *testing.T) { + sess, err := session.NewSession(&aws.Config{ + Region: aws.String("us-east-1"), + Endpoint: aws.String("http://localhost:4566"), + S3ForcePathStyle: aws.Bool(true), + }) + if err != nil { + t.Fatalf("Failed to create session: %v", err) + } + + svc := dynamodb.New(sess) + + result, err := svc.ListTables(&dynamodb.ListTablesInput{}) + if err != nil { + t.Fatalf("Failed to list buckets: %v", err) + } + + if len(result.TableNames) == 0 { + t.Fatal("No tables created") + } + + assert.Equal(t, *result.TableNames[0], "cdktesttable") + }, + Targets: []string{"stacks"}, + }, { Name: "Cloudformation example", OrgYaml: ` @@ -992,7 +1057,6 @@ Organization: t.Fatal("No tables created") } - fmt.Println("table name", *result.TableNames[0]) assert.Equal(t, *result.TableNames[0], "test") }, Targets: []string{"stacks"},