diff --git a/.changelog/27000.txt b/.changelog/27000.txt new file mode 100644 index 00000000000..2742420743c --- /dev/null +++ b/.changelog/27000.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_inspector2_organization_configuration +``` \ No newline at end of file diff --git a/.ci/.semgrep-service-name0.yml b/.ci/.semgrep-service-name0.yml index 350dcaee5b2..595a94d5808 100644 --- a/.ci/.semgrep-service-name0.yml +++ b/.ci/.semgrep-service-name0.yml @@ -2998,3 +2998,33 @@ rules: patterns: - pattern-regex: "(?i)ConfigService" severity: WARNING + - id: configservice-in-var-name + languages: + - go + message: Do not use "ConfigService" in var name inside configservice package + paths: + include: + - internal/service/configservice + patterns: + - pattern: var $NAME = ... + - metavariable-pattern: + metavariable: $NAME + patterns: + - pattern-regex: "(?i)ConfigService" + severity: WARNING + - id: connect-in-func-name + languages: + - go + message: Do not use "Connect" in func name inside connect package + paths: + include: + - internal/service/connect + patterns: + - pattern: func $NAME( ... ) { ... } + - metavariable-pattern: + metavariable: $NAME + patterns: + - pattern-regex: "(?i)Connect" + - pattern-not-regex: .*uickConnect.* + - pattern-not-regex: ^TestAcc.* + severity: WARNING diff --git a/.ci/.semgrep-service-name1.yml b/.ci/.semgrep-service-name1.yml index b5895bfc98b..13f1003ba07 100644 --- a/.ci/.semgrep-service-name1.yml +++ b/.ci/.semgrep-service-name1.yml @@ -1,35 +1,5 @@ # Generated by internal/generate/servicesemgrep/main.go; DO NOT EDIT. rules: - - id: configservice-in-var-name - languages: - - go - message: Do not use "ConfigService" in var name inside configservice package - paths: - include: - - internal/service/configservice - patterns: - - pattern: var $NAME = ... - - metavariable-pattern: - metavariable: $NAME - patterns: - - pattern-regex: "(?i)ConfigService" - severity: WARNING - - id: connect-in-func-name - languages: - - go - message: Do not use "Connect" in func name inside connect package - paths: - include: - - internal/service/connect - patterns: - - pattern: func $NAME( ... ) { ... } - - metavariable-pattern: - metavariable: $NAME - patterns: - - pattern-regex: "(?i)Connect" - - pattern-not-regex: .*uickConnect.* - - pattern-not-regex: ^TestAcc.* - severity: WARNING - id: connect-in-test-name languages: - go @@ -3002,3 +2972,47 @@ rules: patterns: - pattern-regex: "(?i)ImageBuilder" severity: WARNING + - id: inspector-in-func-name + languages: + - go + message: Do not use "Inspector" in func name inside inspector package + paths: + include: + - internal/service/inspector + patterns: + - pattern: func $NAME( ... ) { ... } + - metavariable-pattern: + metavariable: $NAME + patterns: + - pattern-regex: "(?i)Inspector" + - pattern-not-regex: ^TestAcc.* + severity: WARNING + - id: inspector-in-test-name + languages: + - go + message: Include "Inspector" in test name + paths: + include: + - internal/service/inspector/*_test.go + patterns: + - pattern: func $NAME( ... ) { ... } + - metavariable-pattern: + metavariable: $NAME + patterns: + - pattern-not-regex: "^TestAccInspector" + - pattern-regex: ^TestAcc.* + severity: WARNING + - id: inspector-in-const-name + languages: + - go + message: Do not use "Inspector" in const name inside inspector package + paths: + include: + - internal/service/inspector + patterns: + - pattern: const $NAME = ... + - metavariable-pattern: + metavariable: $NAME + patterns: + - pattern-regex: "(?i)Inspector" + severity: WARNING diff --git a/.ci/.semgrep-service-name2.yml b/.ci/.semgrep-service-name2.yml index 375790c0ce9..7b2098ded1a 100644 --- a/.ci/.semgrep-service-name2.yml +++ b/.ci/.semgrep-service-name2.yml @@ -1,62 +1,119 @@ # Generated by internal/generate/servicesemgrep/main.go; DO NOT EDIT. rules: - - id: inspector-in-func-name + - id: inspector-in-var-name languages: - go - message: Do not use "Inspector" in func name inside inspector package + message: Do not use "Inspector" in var name inside inspector package paths: include: - internal/service/inspector patterns: - - pattern: func $NAME( ... ) { ... } + - pattern: var $NAME = ... - metavariable-pattern: metavariable: $NAME patterns: - pattern-regex: "(?i)Inspector" + severity: WARNING + - id: inspector2-in-func-name + languages: + - go + message: Do not use "Inspector2" in func name inside inspector2 package + paths: + include: + - internal/service/inspector2 + patterns: + - pattern: func $NAME( ... ) { ... } + - metavariable-pattern: + metavariable: $NAME + patterns: + - pattern-regex: "(?i)Inspector2" - pattern-not-regex: ^TestAcc.* severity: WARNING - - id: inspector-in-test-name + - id: inspector2-in-test-name languages: - go - message: Include "Inspector" in test name + message: Include "Inspector2" in test name paths: include: - - internal/service/inspector/*_test.go + - internal/service/inspector2/*_test.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: metavariable: $NAME patterns: - - pattern-not-regex: "^TestAccInspector" + - pattern-not-regex: "^TestAccInspector2" - pattern-regex: ^TestAcc.* severity: WARNING - - id: inspector-in-const-name + - id: inspector2-in-const-name languages: - go - message: Do not use "Inspector" in const name inside inspector package + message: Do not use "Inspector2" in const name inside inspector2 package paths: include: - - internal/service/inspector + - internal/service/inspector2 patterns: - pattern: const $NAME = ... - metavariable-pattern: metavariable: $NAME patterns: - - pattern-regex: "(?i)Inspector" + - pattern-regex: "(?i)Inspector2" severity: WARNING - - id: inspector-in-var-name + - id: inspector2-in-var-name languages: - go - message: Do not use "Inspector" in var name inside inspector package + message: Do not use "Inspector2" in var name inside inspector2 package paths: include: - - internal/service/inspector + - internal/service/inspector2 patterns: - pattern: var $NAME = ... - metavariable-pattern: metavariable: $NAME patterns: - - pattern-regex: "(?i)Inspector" + - pattern-regex: "(?i)Inspector2" + severity: WARNING + - id: inspectorv2-in-func-name + languages: + - go + message: Do not use "inspectorv2" in func name inside inspector2 package + paths: + include: + - internal/service/inspector2 + patterns: + - pattern: func $NAME( ... ) { ... } + - metavariable-pattern: + metavariable: $NAME + patterns: + - pattern-regex: "(?i)inspectorv2" + - pattern-not-regex: ^TestAcc.* + severity: WARNING + - id: inspectorv2-in-const-name + languages: + - go + message: Do not use "inspectorv2" in const name inside inspector2 package + paths: + include: + - internal/service/inspector2 + patterns: + - pattern: const $NAME = ... + - metavariable-pattern: + metavariable: $NAME + patterns: + - pattern-regex: "(?i)inspectorv2" + severity: WARNING + - id: inspectorv2-in-var-name + languages: + - go + message: Do not use "inspectorv2" in var name inside inspector2 package + paths: + include: + - internal/service/inspector2 + patterns: + - pattern: var $NAME = ... + - metavariable-pattern: + metavariable: $NAME + patterns: + - pattern-regex: "(?i)inspectorv2" severity: WARNING - id: iot-in-func-name languages: @@ -2969,32 +3026,3 @@ rules: - pattern-regex: "(?i)Redshift" - pattern-not-regex: ^TestAcc.* severity: WARNING - - id: redshift-in-test-name - languages: - - go - message: Include "Redshift" in test name - paths: - include: - - internal/service/redshift/*_test.go - patterns: - - pattern: func $NAME( ... ) { ... } - - metavariable-pattern: - metavariable: $NAME - patterns: - - pattern-not-regex: "^TestAccRedshift" - - pattern-regex: ^TestAcc.* - severity: WARNING - - id: redshift-in-const-name - languages: - - go - message: Do not use "Redshift" in const name inside redshift package - paths: - include: - - internal/service/redshift - patterns: - - pattern: const $NAME = ... - - metavariable-pattern: - metavariable: $NAME - patterns: - - pattern-regex: "(?i)Redshift" - severity: WARNING diff --git a/.ci/.semgrep-service-name3.yml b/.ci/.semgrep-service-name3.yml index 25efae7d9b4..8551e5822e0 100644 --- a/.ci/.semgrep-service-name3.yml +++ b/.ci/.semgrep-service-name3.yml @@ -1,5 +1,34 @@ # Generated by internal/generate/servicesemgrep/main.go; DO NOT EDIT. rules: + - id: redshift-in-test-name + languages: + - go + message: Include "Redshift" in test name + paths: + include: + - internal/service/redshift/*_test.go + patterns: + - pattern: func $NAME( ... ) { ... } + - metavariable-pattern: + metavariable: $NAME + patterns: + - pattern-not-regex: "^TestAccRedshift" + - pattern-regex: ^TestAcc.* + severity: WARNING + - id: redshift-in-const-name + languages: + - go + message: Do not use "Redshift" in const name inside redshift package + paths: + include: + - internal/service/redshift + patterns: + - pattern: const $NAME = ... + - metavariable-pattern: + metavariable: $NAME + patterns: + - pattern-regex: "(?i)Redshift" + severity: WARNING - id: redshift-in-var-name languages: - go diff --git a/.teamcity/components/generated/services_all.kt b/.teamcity/components/generated/services_all.kt index 12a68add637..941790109b8 100644 --- a/.teamcity/components/generated/services_all.kt +++ b/.teamcity/components/generated/services_all.kt @@ -90,6 +90,7 @@ val services = mapOf( "identitystore" to ServiceSpec("SSO Identity Store"), "imagebuilder" to ServiceSpec("EC2 Image Builder"), "inspector" to ServiceSpec("Inspector"), + "inspector2" to ServiceSpec("Inspector V2"), "iot" to ServiceSpec("IoT Core"), "iotanalytics" to ServiceSpec("IoT Analytics"), "iotevents" to ServiceSpec("IoT Events"), diff --git a/GNUmakefile b/GNUmakefile index 5603aabef42..6a8352521f8 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -5,6 +5,7 @@ PKG_NAME ?= internal TEST_COUNT ?= 1 ACCTEST_TIMEOUT ?= 180m ACCTEST_PARALLELISM ?= 20 +GO_VER ?= go ifneq ($(origin PKG), undefined) PKG_NAME = internal/service/$(PKG) @@ -57,7 +58,7 @@ endif default: build build: fmtcheck - go install + $(GO_VER) install gen: rm -f .github/labeler-issue-triage.yml @@ -73,15 +74,15 @@ gen: rm -f .ci/.semgrep-caps-aws-ec2.yml rm -f .ci/.semgrep-configs.yml rm -f .ci/.semgrep-service-name*.yml - go generate ./... + $(GO_VER) generate ./... sweep: # make sweep SWEEPARGS=-sweep-run=aws_example_thing @echo "WARNING: This will destroy infrastructure. Use only in development accounts." - go test $(SWEEP_DIR) -v -tags=sweep -sweep=$(SWEEP) $(SWEEPARGS) -timeout 60m + $(GO_VER) test $(SWEEP_DIR) -v -tags=sweep -sweep=$(SWEEP) $(SWEEPARGS) -timeout 60m test: fmtcheck - go test $(TEST) $(TESTARGS) -timeout=5m + $(GO_VER) test $(TEST) $(TESTARGS) -timeout=5m testacc: fmtcheck @if [ "$(TESTARGS)" = "-run=TestAccXXX" ]; then \ @@ -94,7 +95,7 @@ testacc: fmtcheck echo "See the contributing guide for more information: https://github.com/hashicorp/terraform-provider-aws/blob/main/docs/contributing/running-and-writing-acceptance-tests.md"; \ exit 1; \ fi - TF_ACC=1 go test ./$(PKG_NAME)/... -v -count $(TEST_COUNT) -parallel $(ACCTEST_PARALLELISM) $(RUNARGS) $(TESTARGS) -timeout $(ACCTEST_TIMEOUT) + TF_ACC=1 $(GO_VER) test ./$(PKG_NAME)/... -v -count $(TEST_COUNT) -parallel $(ACCTEST_PARALLELISM) $(RUNARGS) $(TESTARGS) -timeout $(ACCTEST_TIMEOUT) fmt: @echo "==> Fixing source code with gofmt..." @@ -116,7 +117,7 @@ generate-changelog: depscheck: @echo "==> Checking source code with go mod tidy..." - @go mod tidy + @$(GO_VER) mod tidy @git diff --exit-code -- go.mod go.sum || \ (echo; echo "Unexpected difference in go.mod/go.sum files. Run 'go mod tidy' command or revert any go.mod/go.sum changes and commit."; exit 1) @@ -186,15 +187,15 @@ importlint: @impi --local . --scheme stdThirdPartyLocal ./$(PKG_NAME)/... tools: - cd .ci/providerlint && go install . - cd .ci/tools && go install github.com/bflad/tfproviderdocs - cd .ci/tools && go install github.com/client9/misspell/cmd/misspell - cd .ci/tools && go install github.com/golangci/golangci-lint/cmd/golangci-lint - cd .ci/tools && go install github.com/katbyte/terrafmt - cd .ci/tools && go install github.com/terraform-linters/tflint - cd .ci/tools && go install github.com/pavius/impi/cmd/impi - cd .ci/tools && go install github.com/hashicorp/go-changelog/cmd/changelog-build - cd .ci/tools && go install github.com/rhysd/actionlint/cmd/actionlint + cd .ci/providerlint && $(GO_VER) install . + cd .ci/tools && $(GO_VER) install github.com/bflad/tfproviderdocs + cd .ci/tools && $(GO_VER) install github.com/client9/misspell/cmd/misspell + cd .ci/tools && $(GO_VER) install github.com/golangci/golangci-lint/cmd/golangci-lint + cd .ci/tools && $(GO_VER) install github.com/katbyte/terrafmt + cd .ci/tools && $(GO_VER) install github.com/terraform-linters/tflint + cd .ci/tools && $(GO_VER) install github.com/pavius/impi/cmd/impi + cd .ci/tools && $(GO_VER) install github.com/hashicorp/go-changelog/cmd/changelog-build + cd .ci/tools && $(GO_VER) install github.com/rhysd/actionlint/cmd/actionlint test-compile: @if [ "$(TEST)" = "./..." ]; then \ @@ -202,7 +203,7 @@ test-compile: echo " make test-compile TEST=./$(PKG_NAME)"; \ exit 1; \ fi - go test -c $(TEST) $(TESTARGS) + $(GO_VER) test -c $(TEST) $(TESTARGS) website-link-check: @.ci/scripts/markdown-link-check.sh @@ -254,10 +255,10 @@ semall: --config 'r/dgryski.semgrep-go.oserrors' skaff: - cd skaff && go install github.com/hashicorp/terraform-provider-aws/skaff + cd skaff && $(GO_VER) install github.com/hashicorp/terraform-provider-aws/skaff tfsdk2fw: - cd tools/tfsdk2fw && go install github.com/hashicorp/terraform-provider-aws/tools/tfsdk2fw + cd tools/tfsdk2fw && $(GO_VER) install github.com/hashicorp/terraform-provider-aws/tools/tfsdk2fw yamllint: @yamllint . diff --git a/go.mod b/go.mod index 3f78700d0f3..133d0e7459f 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/comprehend v1.18.10 github.com/aws/aws-sdk-go-v2/service/fis v1.12.15 github.com/aws/aws-sdk-go-v2/service/identitystore v1.15.2 + github.com/aws/aws-sdk-go-v2/service/inspector2 v1.8.1 github.com/aws/aws-sdk-go-v2/service/kendra v1.33.3 github.com/aws/aws-sdk-go-v2/service/medialive v1.22.7 github.com/aws/aws-sdk-go-v2/service/rolesanywhere v1.0.7 @@ -50,8 +51,8 @@ require ( github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/aws/aws-sdk-go-v2/config v1.15.4 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.12.0 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.15 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.3.11 // indirect github.com/aws/aws-sdk-go-v2/service/iam v1.18.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.4 // indirect diff --git a/go.sum b/go.sum index 319a50d3366..9f70a5c3f1d 100644 --- a/go.sum +++ b/go.sum @@ -34,11 +34,13 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.4/go.mod h1:u/s5/Z+ohUQOPXl0 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.15 h1:nkQ+aI0OCeYfzrBipL6ja/6VEbUnHQoZHBHtoK+Nzxw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.15/go.mod h1:Oz2/qWINxIgSmoZT9adpxJy2UhpcOAI3TIyWgYMVSz0= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.10/go.mod h1:F+EZtuIwjlv35kRJPyBGcsA4f7bnSoz15zOQ2lJq1Z4= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.21 h1:gRIXnmAVNyoRQywdNtpAkgY+f30QNzgF53Q5OobNZZs= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.21/go.mod h1:XsmHMV9c512xgsW01q7H0ut+UQQQpWX8QsFbdLHDwaU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23 h1:s4g/wnzMf+qepSNgTvaQQHNxyMLKSawNhKCPNy++2xY= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23/go.mod h1:2DFxAQ9pfIRy0imBCJv+vZ2X6RKxves6fbnEuSry6b4= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.4/go.mod h1:8glyUqVIM4AmeenIsPo0oVh3+NUwnsQml2OFupfQW+0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.15 h1:noAhOo2mMDyYhTx99aYPvQw16T3fQ/DiKAv9fzpIKH8= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.15/go.mod h1:kjJ4CyD9M3Wq88GYg3IPfj67Rs0Uvz8aXK7MJ8BvE4I= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17 h1:/K482T5A3623WJgWT8w1yRAFK4RzGzEl7y39yhtn9eA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17/go.mod h1:pRwaTYCJemADaqCbUAxltMoHKata7hmB5PjEXeu0kfg= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.11 h1:6cZRymlLEIlDTEB0+5+An6Zj1CKt6rSE69tOmFeu1nk= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.11/go.mod h1:0MR+sS1b/yxsfAPvAESrw8NfwUoxMinDyw6EYR9BS2U= github.com/aws/aws-sdk-go-v2/service/comprehend v1.18.10 h1:9eE1yKoQzF5EfifB4KX9uNVeA3A7XnY9AJoNPyamKZc= @@ -49,6 +51,8 @@ github.com/aws/aws-sdk-go-v2/service/iam v1.18.4 h1:E41guA79mjEbwJdh0zXz1d8+Zt4z github.com/aws/aws-sdk-go-v2/service/iam v1.18.4/go.mod h1:FpNvAfCZyIQ3qeNJUOw4CShKvdizHblXqAvSk0qmyL4= github.com/aws/aws-sdk-go-v2/service/identitystore v1.15.2 h1:TqJ7znv3Ve5jM3gm0wepI9OX1drWe8tdM0SfkgVD/Vo= github.com/aws/aws-sdk-go-v2/service/identitystore v1.15.2/go.mod h1:CB/VwTcXlBFgjkKW1uqU8BYGinF/Iw42pHO4sQPiNUE= +github.com/aws/aws-sdk-go-v2/service/inspector2 v1.8.1 h1:Q4OBuhQrSt1/T8hyy5nwuxwT9vDezsADQt8x4eDj3Z4= +github.com/aws/aws-sdk-go-v2/service/inspector2 v1.8.1/go.mod h1:ijgzkrNZIbIzkWFET1RpQ1G46eFYmdoEx8yh6OUuXso= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.4 h1:b16QW0XWl0jWjLABFc1A+uh145Oqv+xDcObNk0iQgUk= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.4/go.mod h1:uKkN7qmSIsNJVyMtxNQoCEYMvFEXbOg9fwCJPdfp2u8= github.com/aws/aws-sdk-go-v2/service/kendra v1.33.3 h1:TE6o6iq+Z5MVA96FO6lo1PmZcJKmvveVmo8DlpDScyw= diff --git a/internal/conns/awsclient_gen.go b/internal/conns/awsclient_gen.go index c2dab558e46..015e9369d07 100644 --- a/internal/conns/awsclient_gen.go +++ b/internal/conns/awsclient_gen.go @@ -5,6 +5,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/comprehend" "github.com/aws/aws-sdk-go-v2/service/fis" "github.com/aws/aws-sdk-go-v2/service/identitystore" + "github.com/aws/aws-sdk-go-v2/service/inspector2" "github.com/aws/aws-sdk-go-v2/service/kendra" "github.com/aws/aws-sdk-go-v2/service/medialive" "github.com/aws/aws-sdk-go-v2/service/rolesanywhere" @@ -143,7 +144,6 @@ import ( "github.com/aws/aws-sdk-go/service/iam" "github.com/aws/aws-sdk-go/service/imagebuilder" "github.com/aws/aws-sdk-go/service/inspector" - "github.com/aws/aws-sdk-go/service/inspector2" "github.com/aws/aws-sdk-go/service/iot" "github.com/aws/aws-sdk-go/service/iot1clickdevicesservice" "github.com/aws/aws-sdk-go/service/iot1clickprojects" @@ -457,7 +457,7 @@ type AWSClient struct { IdentityStoreConn *identitystore.Client ImageBuilderConn *imagebuilder.Imagebuilder InspectorConn *inspector.Inspector - Inspector2Conn *inspector2.Inspector2 + Inspector2Conn *inspector2.Client IoTConn *iot.IoT IoT1ClickDevicesConn *iot1clickdevicesservice.IoT1ClickDevicesService IoT1ClickProjectsConn *iot1clickprojects.IoT1ClickProjects diff --git a/internal/conns/config.go b/internal/conns/config.go index 2737b0b2f85..1804c9c2b7e 100644 --- a/internal/conns/config.go +++ b/internal/conns/config.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/comprehend" "github.com/aws/aws-sdk-go-v2/service/fis" "github.com/aws/aws-sdk-go-v2/service/identitystore" + "github.com/aws/aws-sdk-go-v2/service/inspector2" "github.com/aws/aws-sdk-go-v2/service/kendra" "github.com/aws/aws-sdk-go-v2/service/medialive" "github.com/aws/aws-sdk-go-v2/service/rolesanywhere" @@ -215,6 +216,12 @@ func (c *Config) ConfigureProvider(ctx context.Context, client *AWSClient) (*AWS } }) + client.Inspector2Conn = inspector2.NewFromConfig(cfg, func(o *inspector2.Options) { + if endpoint := c.Endpoints[names.Inspector2]; endpoint != "" { + o.EndpointResolver = inspector2.EndpointResolverFromURL(endpoint) + } + }) + client.KendraConn = kendra.NewFromConfig(cfg, func(o *kendra.Options) { if endpoint := c.Endpoints[names.Kendra]; endpoint != "" { o.EndpointResolver = kendra.EndpointResolverFromURL(endpoint) diff --git a/internal/conns/config_gen.go b/internal/conns/config_gen.go index 952bf1a44f3..12cfb46373e 100644 --- a/internal/conns/config_gen.go +++ b/internal/conns/config_gen.go @@ -135,7 +135,6 @@ import ( "github.com/aws/aws-sdk-go/service/iam" "github.com/aws/aws-sdk-go/service/imagebuilder" "github.com/aws/aws-sdk-go/service/inspector" - "github.com/aws/aws-sdk-go/service/inspector2" "github.com/aws/aws-sdk-go/service/iot" "github.com/aws/aws-sdk-go/service/iot1clickdevicesservice" "github.com/aws/aws-sdk-go/service/iot1clickprojects" @@ -424,7 +423,6 @@ func (c *Config) clientConns(client *AWSClient, sess *session.Session) { client.IVSConn = ivs.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[names.IVS])})) client.ImageBuilderConn = imagebuilder.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[names.ImageBuilder])})) client.InspectorConn = inspector.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[names.Inspector])})) - client.Inspector2Conn = inspector2.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[names.Inspector2])})) client.IoTConn = iot.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[names.IoT])})) client.IoT1ClickDevicesConn = iot1clickdevicesservice.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[names.IoT1ClickDevices])})) client.IoT1ClickProjectsConn = iot1clickprojects.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[names.IoT1ClickProjects])})) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 5e18e322039..defa549d5b6 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -105,6 +105,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/service/identitystore" "github.com/hashicorp/terraform-provider-aws/internal/service/imagebuilder" "github.com/hashicorp/terraform-provider-aws/internal/service/inspector" + "github.com/hashicorp/terraform-provider-aws/internal/service/inspector2" "github.com/hashicorp/terraform-provider-aws/internal/service/iot" "github.com/hashicorp/terraform-provider-aws/internal/service/kafka" "github.com/hashicorp/terraform-provider-aws/internal/service/kafkaconnect" @@ -1616,6 +1617,8 @@ func New(_ context.Context) (*schema.Provider, error) { "aws_inspector_assessment_template": inspector.ResourceAssessmentTemplate(), "aws_inspector_resource_group": inspector.ResourceResourceGroup(), + "aws_inspector2_organization_configuration": inspector2.ResourceOrganizationConfiguration(), + "aws_iot_authorizer": iot.ResourceAuthorizer(), "aws_iot_certificate": iot.ResourceCertificate(), "aws_iot_indexing_configuration": iot.ResourceIndexingConfiguration(), diff --git a/internal/service/inspector2/organization_configuration.go b/internal/service/inspector2/organization_configuration.go new file mode 100644 index 00000000000..60c40e098f1 --- /dev/null +++ b/internal/service/inspector2/organization_configuration.go @@ -0,0 +1,234 @@ +package inspector2 + +import ( + "context" + "fmt" + "log" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/inspector2" + "github.com/aws/aws-sdk-go-v2/service/inspector2/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func ResourceOrganizationConfiguration() *schema.Resource { + return &schema.Resource{ + CreateWithoutTimeout: resourceOrganizationConfigurationCreate, + ReadWithoutTimeout: resourceOrganizationConfigurationRead, + UpdateWithoutTimeout: resourceOrganizationConfigurationUpdate, + DeleteWithoutTimeout: resourceOrganizationConfigurationDelete, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(5 * time.Minute), + Update: schema.DefaultTimeout(5 * time.Minute), + Delete: schema.DefaultTimeout(5 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "auto_enable": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + MinItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ec2": { + Type: schema.TypeBool, + Required: true, + }, + "ecr": { + Type: schema.TypeBool, + Required: true, + }, + }, + }, + }, + "max_account_limit_reached": { + Type: schema.TypeBool, + Computed: true, + }, + }, + } +} + +const ( + ResNameOrganizationConfiguration = "Organization Configuration" + orgConfigMutex = "f14b54d7-2b10-58c2-9c1b-c48260a4825d" +) + +func resourceOrganizationConfigurationCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + d.SetId(meta.(*conns.AWSClient).AccountID) + return resourceOrganizationConfigurationUpdate(ctx, d, meta) +} + +func resourceOrganizationConfigurationRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).Inspector2Conn + + out, err := conn.DescribeOrganizationConfiguration(ctx, &inspector2.DescribeOrganizationConfigurationInput{}) + + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Inspector2 OrganizationConfiguration (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return create.DiagError(names.Inspector2, create.ErrActionReading, ResNameOrganizationConfiguration, d.Id(), err) + } + + if err := d.Set("auto_enable", []interface{}{flattenAutoEnable(out.AutoEnable)}); err != nil { + return create.DiagError(names.Inspector2, create.ErrActionSetting, ResNameOrganizationConfiguration, d.Id(), err) + } + + d.Set("max_account_limit_reached", out.MaxAccountLimitReached) + + return nil +} + +func resourceOrganizationConfigurationUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).Inspector2Conn + + update := false + + in := &inspector2.UpdateOrganizationConfigurationInput{} + + if d.HasChanges("auto_enable") { + in.AutoEnable = expandAutoEnable(d.Get("auto_enable").([]interface{})[0].(map[string]interface{})) + update = true + } + + if !update { + return nil + } + + conns.GlobalMutexKV.Lock(orgConfigMutex) + defer conns.GlobalMutexKV.Unlock(orgConfigMutex) + + log.Printf("[DEBUG] Updating Inspector2 Organization Configuration (%s): %#v", d.Id(), in) + _, err := conn.UpdateOrganizationConfiguration(ctx, in) + if err != nil { + return create.DiagError(names.Inspector2, create.ErrActionUpdating, ResNameOrganizationConfiguration, d.Id(), err) + } + + if err := waitOrganizationConfigurationUpdated(ctx, conn, d.Get("auto_enable.0.ec2").(bool), d.Get("auto_enable.0.ecr").(bool), d.Timeout(schema.TimeoutUpdate)); err != nil { + return create.DiagError(names.Inspector2, create.ErrActionWaitingForUpdate, ResNameOrganizationConfiguration, d.Id(), err) + } + + return resourceOrganizationConfigurationRead(ctx, d, meta) +} + +func resourceOrganizationConfigurationDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).Inspector2Conn + + conns.GlobalMutexKV.Lock(orgConfigMutex) + defer conns.GlobalMutexKV.Unlock(orgConfigMutex) + + in := &inspector2.UpdateOrganizationConfigurationInput{ + AutoEnable: &types.AutoEnable{ + Ec2: aws.Bool(false), + Ecr: aws.Bool(false), + }, + } + + log.Printf("[DEBUG] Setting Inspector2 Organization Configuration (%s): %#v", d.Id(), in) + _, err := conn.UpdateOrganizationConfiguration(ctx, in) + if err != nil { + return create.DiagError(names.Inspector2, create.ErrActionUpdating, ResNameOrganizationConfiguration, d.Id(), err) + } + + if err := waitOrganizationConfigurationUpdated(ctx, conn, false, false, d.Timeout(schema.TimeoutUpdate)); err != nil { + return create.DiagError(names.Inspector2, create.ErrActionWaitingForUpdate, ResNameOrganizationConfiguration, d.Id(), err) + } + + return nil +} + +func waitOrganizationConfigurationUpdated(ctx context.Context, conn *inspector2.Client, ec2, ecr bool, timeout time.Duration) error { + needle := fmt.Sprintf("%t:%t", ec2, ecr) + + all := []string{ + fmt.Sprintf("%t:%t", false, false), + fmt.Sprintf("%t:%t", false, true), + fmt.Sprintf("%t:%t", true, false), + fmt.Sprintf("%t:%t", true, true), + } + + for i, v := range all { + if v == needle { + all = append(all[:i], all[i+1:]...) + break + } + } + + stateConf := &resource.StateChangeConf{ + Pending: all, + Target: []string{needle}, + Refresh: statusOrganizationConfiguration(ctx, conn), + Timeout: timeout, + NotFoundChecks: 20, + ContinuousTargetOccurence: 2, + MinTimeout: time.Second * 5, + } + + _, err := stateConf.WaitForStateContext(ctx) + + return err +} + +func statusOrganizationConfiguration(ctx context.Context, conn *inspector2.Client) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + out, err := conn.DescribeOrganizationConfiguration(ctx, &inspector2.DescribeOrganizationConfigurationInput{}) + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return out, fmt.Sprintf("%t:%t", aws.ToBool(out.AutoEnable.Ec2), aws.ToBool(out.AutoEnable.Ecr)), nil + } +} + +func flattenAutoEnable(apiObject *types.AutoEnable) map[string]interface{} { + if apiObject == nil { + return nil + } + + m := map[string]interface{}{} + + if v := apiObject.Ec2; v != nil { + m["ec2"] = aws.ToBool(v) + } + + if v := apiObject.Ecr; v != nil { + m["ecr"] = aws.ToBool(v) + } + + return m +} + +func expandAutoEnable(tfMap map[string]interface{}) *types.AutoEnable { + if tfMap == nil { + return nil + } + + a := &types.AutoEnable{} + + if v, ok := tfMap["ec2"].(bool); ok { + a.Ec2 = aws.Bool(v) + } + + if v, ok := tfMap["ecr"].(bool); ok { + a.Ecr = aws.Bool(v) + } + + return a +} diff --git a/internal/service/inspector2/organization_configuration_test.go b/internal/service/inspector2/organization_configuration_test.go new file mode 100644 index 00000000000..6bcf0f3b8c2 --- /dev/null +++ b/internal/service/inspector2/organization_configuration_test.go @@ -0,0 +1,187 @@ +package inspector2_test + +import ( + "context" + "errors" + "fmt" + "strings" + "testing" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/inspector2" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + tfinspector2 "github.com/hashicorp/terraform-provider-aws/internal/service/inspector2" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccInspector2OrganizationConfiguration_serial(t *testing.T) { + testCases := map[string]func(t *testing.T){ + "basic": testAccOrganizationConfiguration_basic, + "disappears": testAccOrganizationConfiguration_disappears, + "ec2ECR": testAccOrganizationConfiguration_ec2ECR, + } + + for name, tc := range testCases { + tc := tc + t.Run(name, func(t *testing.T) { + tc(t) + }) + } +} + +func testAccOrganizationConfiguration_basic(t *testing.T) { + resourceName := "aws_inspector2_organization_configuration.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(names.Inspector2EndpointID, t) + testAccPreCheck(t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.Inspector2EndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckOrganizationConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccOrganizationConfigurationConfig_basic(true, false), + Check: resource.ComposeTestCheckFunc( + testAccCheckOrganizationConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auto_enable.0.ec2", "true"), + resource.TestCheckResourceAttr(resourceName, "auto_enable.0.ecr", "false"), + ), + }, + }, + }) +} + +func testAccOrganizationConfiguration_disappears(t *testing.T) { + resourceName := "aws_inspector2_organization_configuration.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(names.Inspector2EndpointID, t) + testAccPreCheck(t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.Inspector2EndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckOrganizationConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccOrganizationConfigurationConfig_basic(true, false), + Check: resource.ComposeTestCheckFunc( + testAccCheckOrganizationConfigurationExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfinspector2.ResourceOrganizationConfiguration(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccOrganizationConfiguration_ec2ECR(t *testing.T) { + resourceName := "aws_inspector2_organization_configuration.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(names.Inspector2EndpointID, t) + testAccPreCheck(t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.Inspector2EndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckOrganizationConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccOrganizationConfigurationConfig_basic(true, true), + Check: resource.ComposeTestCheckFunc( + testAccCheckOrganizationConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auto_enable.0.ec2", "true"), + resource.TestCheckResourceAttr(resourceName, "auto_enable.0.ecr", "true"), + ), + }, + }, + }) +} + +func testAccCheckOrganizationConfigurationDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).Inspector2Conn + ctx := context.Background() + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_inspector2_organization_configuration" { + continue + } + + out, err := conn.DescribeOrganizationConfiguration(ctx, &inspector2.DescribeOrganizationConfigurationInput{}) + if err != nil { + return create.Error(names.Inspector2, create.ErrActionCheckingDestroyed, tfinspector2.ResNameOrganizationConfiguration, rs.Primary.ID, err) + } + + if out != nil && out.AutoEnable != nil && !aws.ToBool(out.AutoEnable.Ec2) && !aws.ToBool(out.AutoEnable.Ecr) { + return nil + } + + return create.Error(names.Inspector2, create.ErrActionCheckingDestroyed, tfinspector2.ResNameOrganizationConfiguration, rs.Primary.ID, errors.New("not destroyed")) + } + + return nil +} + +func testAccCheckOrganizationConfigurationExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return create.Error(names.Inspector2, create.ErrActionCheckingExistence, tfinspector2.ResNameOrganizationConfiguration, name, errors.New("not found")) + } + + if rs.Primary.ID == "" { + return create.Error(names.Inspector2, create.ErrActionCheckingExistence, tfinspector2.ResNameOrganizationConfiguration, name, errors.New("not set")) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).Inspector2Conn + ctx := context.Background() + _, err := conn.DescribeOrganizationConfiguration(ctx, &inspector2.DescribeOrganizationConfigurationInput{}) + + if err != nil { + return create.Error(names.Inspector2, create.ErrActionCheckingExistence, tfinspector2.ResNameOrganizationConfiguration, rs.Primary.ID, err) + } + + return nil + } +} + +func testAccPreCheck(t *testing.T) { + conn := acctest.Provider.Meta().(*conns.AWSClient).Inspector2Conn + ctx := context.Background() + + _, err := conn.DescribeOrganizationConfiguration(ctx, &inspector2.DescribeOrganizationConfigurationInput{}) + + if acctest.PreCheckSkipError(err) { + t.Skipf("skipping acceptance testing: %s", err) + } + + if err != nil && strings.Contains(err.Error(), "Invoking account does not") { + // does not have code AccessDeniedException despite having that in the text + t.Skipf("to run this test, enable this account as a Delegated Admin Account: %s", err) + } + + if err != nil { + t.Fatalf("unexpected PreCheck error: %s", err) + } +} + +func testAccOrganizationConfigurationConfig_basic(ec2, ecr bool) string { + return fmt.Sprintf(` +resource "aws_inspector2_organization_configuration" "test" { + auto_enable { + ec2 = %[1]t + ecr = %[2]t + } +} +`, ec2, ecr) +} diff --git a/names/names.go b/names/names.go index 7df2afa6dd9..0105d011f66 100644 --- a/names/names.go +++ b/names/names.go @@ -25,6 +25,7 @@ import ( const ( ComprehendEndpointID = "comprehend" IdentityStoreEndpointID = "identitystore" + Inspector2EndpointID = "inspector2" KendraEndpointID = "kendra" MediaLiveEndpointID = "medialive" RolesAnywhereEndpointID = "rolesanywhere" diff --git a/names/names_data.csv b/names/names_data.csv index 2b033fb05fa..00d1af3a23e 100644 --- a/names/names_data.csv +++ b/names/names_data.csv @@ -168,7 +168,7 @@ honeycode,honeycode,honeycode,honeycode,,honeycode,,,Honeycode,Honeycode,,1,,aws iam,iam,iam,iam,,iam,,,IAM,IAM,,1,,aws_iam_,,iam_,IAM (Identity & Access Management),AWS,,,AWS_IAM_ENDPOINT,TF_AWS_IAM_ENDPOINT, accessanalyzer,accessanalyzer,accessanalyzer,accessanalyzer,,accessanalyzer,,,AccessAnalyzer,AccessAnalyzer,,1,,aws_accessanalyzer_,,accessanalyzer_,IAM Access Analyzer,AWS,,,,, inspector,inspector,inspector,inspector,,inspector,,,Inspector,Inspector,,1,,aws_inspector_,,inspector_,Inspector,Amazon,,,,, -inspector2,inspector2,inspector2,inspector2,,inspector2,,,Inspector2,Inspector2,,1,,aws_inspector2_,,inspector2_,Inspector V2,Amazon,,,,, +inspector2,inspector2,inspector2,inspector2,,inspector2,,inspectorv2,Inspector2,Inspector2,x,2,,aws_inspector2_,,inspector2_,Inspector V2,Amazon,,,,, iot1click-devices,iot1clickdevices,iot1clickdevicesservice,iot1clickdevicesservice,,iot1clickdevices,,iot1clickdevicesservice,IoT1ClickDevices,IoT1ClickDevicesService,,1,,aws_iot1clickdevices_,,iot1clickdevices_,IoT 1-Click Devices,AWS,,,,, iot1click-projects,iot1clickprojects,iot1clickprojects,iot1clickprojects,,iot1clickprojects,,,IoT1ClickProjects,IoT1ClickProjects,,1,,aws_iot1clickprojects_,,iot1clickprojects_,IoT 1-Click Projects,AWS,,,,, iotanalytics,iotanalytics,iotanalytics,iotanalytics,,iotanalytics,,,IoTAnalytics,IoTAnalytics,,1,,aws_iotanalytics_,,iotanalytics_,IoT Analytics,AWS,,,,, diff --git a/website/docs/guides/custom-service-endpoints.html.md b/website/docs/guides/custom-service-endpoints.html.md index ca5a9e4698b..41aaad1b47b 100644 --- a/website/docs/guides/custom-service-endpoints.html.md +++ b/website/docs/guides/custom-service-endpoints.html.md @@ -202,7 +202,7 @@ provider "aws" {
  • identitystore
  • imagebuilder
  • inspector
  • -
  • inspector2
  • +
  • inspector2 (or inspectorv2)
  • iot
  • iot1clickdevices (or iot1clickdevicesservice)
  • iot1clickprojects
  • diff --git a/website/docs/r/inspector2_organization_configuration.html.markdown b/website/docs/r/inspector2_organization_configuration.html.markdown new file mode 100644 index 00000000000..06fc2f23c0f --- /dev/null +++ b/website/docs/r/inspector2_organization_configuration.html.markdown @@ -0,0 +1,53 @@ +--- +subcategory: "Inspector V2" +layout: "aws" +page_title: "AWS: aws_inspector2_organization_configuration" +description: |- + Terraform resource for managing an AWS Inspector V2 Organization Configuration. +--- + +# Resource: aws_inspector2_organization_configuration + +Terraform resource for managing an AWS Inspector V2 Organization Configuration. + +~> **NOTE:** In order for this resource to work, the account you use must be an Inspector V2 Delegated Admin Account. + +~> **NOTE:** When this resource is deleted, EC2 and ECR scans will no longer be automatically enabled for new members of your Amazon Inspector organization. + +## Example Usage + +### Basic Usage + +```terraform +resource "aws_inspector2_organization_configuration" "example" { + auto_enable { + ec2 = true + ecr = false + } +} +``` + +## Argument Reference + +The following arguments are required: + +* `auto_enable` - (Required) Configuration block for auto enabling. See below. + +### `auto_enable` + +* `ec2` - (Required) Whether Amazon EC2 scans are automatically enabled for new members of your Amazon Inspector organization. +* `ecr` - (Required) Whether Amazon ECR scans are automatically enabled for new members of your Amazon Inspector organization. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `max_account_limit_reached` - Whether your configuration reached the max account limit. + +## Timeouts + +[Configuration options](https://www.terraform.io/docs/configuration/blocks/resources/syntax.html#operation-timeouts): + +* `create` - (Default `5m`) +* `update` - (Default `5m`) +* `delete` - (Default `5m`)