From a00d54237e0eca1b5236b67001f805d1e230df53 Mon Sep 17 00:00:00 2001 From: Ian Duffy Date: Wed, 27 Nov 2024 22:12:38 +0000 Subject: [PATCH 1/8] chore: add pre-commit-config.yaml --- .github/CODE_OF_CONDUCT.md | 2 +- .github/ISSUE_TEMPLATE.md | 17 +- .github/SUPPORT.md | 2 +- .github/workflows/release.yml | 2 +- .markdownlint.yaml | 8 + .pre-commit-config.yaml | 46 ++++++ README.md | 23 ++- docs/data-sources/entitlement_list.md | 3 +- .../organization_list_org_memebrs.md | 2 +- .../organization_member_details.md | 2 +- docs/data-sources/package.md | 46 +++--- docs/data-sources/package_list.md | 1 - docs/data-sources/repository_privileges.md | 22 +-- docs/resources/license_policy.md | 2 +- docs/resources/oidc.md | 2 +- docs/resources/package_deny_policy.md | 2 +- docs/resources/repository_privileges.md | 48 +++--- docs/resources/repository_retention.md | 2 +- docs/resources/service.md | 22 +-- docs/resources/vulnerability_policy.md | 2 +- docs/resources/webhook.md | 30 ++-- examples/flat-example/README.md | 2 +- examples/flat-example/global-variables.tf | 2 - examples/flat-example/org-deny-policy.tf | 10 +- examples/flat-example/org-license-policy.tf | 26 +-- examples/flat-example/org-oidc-config.tf | 18 +- examples/flat-example/org-saml-group.tf | 18 +- examples/flat-example/provider.tf | 12 +- examples/flat-example/repo-devops.tf | 6 +- examples/flat-example/repo-oidc-demo.tf | 2 +- examples/iterative-example/README.md | 4 +- .../iterative-example/global-variables.tf | 18 +- examples/iterative-example/license-policy.tf | 12 +- examples/iterative-example/oidc-config.tf | 16 +- examples/iterative-example/provider.tf | 12 +- examples/iterative-example/repositories.tf | 16 +- examples/iterative-example/teams.tf | 2 +- examples/iterative-example/terraform.tfvars | 16 +- examples/iterative-example/upstreams.tf | 2 +- .../iterative-example/vulnerability-policy.tf | 2 +- go.mod | 2 +- go.sum | 156 +----------------- 42 files changed, 278 insertions(+), 362 deletions(-) create mode 100644 .markdownlint.yaml create mode 100644 .pre-commit-config.yaml diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index 0c8b092..a42cc7d 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -2,4 +2,4 @@ HashiCorp Community Guidelines apply to you when interacting with the community here on GitHub and contributing code. -Please read the full text at https://www.hashicorp.com/community-guidelines +Please read the full text at diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 8066d39..40cd0f5 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,18 +1,22 @@ Hi there, -Thank you for opening an issue. Please note that we try to keep the Terraform issue tracker reserved for bug reports and feature requests. For general usage questions, please see: https://www.terraform.io/community.html. +Thank you for opening an issue. Please note that we try to keep the Terraform issue tracker reserved for bug reports and feature requests. For general usage questions, please see: . ### Terraform Version + Run `terraform -v` to show the version. If you are not running the latest version of Terraform, please upgrade because your issue may have already been fixed. ### Affected Resource(s) + Please list the resources as a list, for example: + - opc_instance - opc_storage_volume If this issue appears to affect multiple resources, it may be an issue with Terraform's core, so please mention this. ### Terraform Configuration Files + ```hcl # Copy-paste your Terraform configurations here - for large Terraform configs, # please use a service like Dropbox and share a link to the ZIP file. For @@ -20,24 +24,33 @@ If this issue appears to affect multiple resources, it may be an issue with Terr ``` ### Debug Output -Please provider a link to a GitHub Gist containing the complete debug output: https://www.terraform.io/docs/internals/debugging.html. Please do NOT paste the debug output in the issue; just paste a link to the Gist. + +Please provider a link to a GitHub Gist containing the complete debug output: . Please do NOT paste the debug output in the issue; just paste a link to the Gist. ### Panic Output + If Terraform produced a panic, please provide a link to a GitHub Gist containing the output of the `crash.log`. ### Expected Behavior + What should have happened? ### Actual Behavior + What actually happened? ### Steps to Reproduce + Please list the steps required to reproduce the issue, for example: + 1. `terraform apply` ### Important Factoids + Are there anything atypical about your accounts that we should know? For example: Running in EC2 Classic? Custom version of OpenStack? Tight ACLs? ### References + Are there any other GitHub issues (open or closed) or Pull Requests that should be linked here? For example: + - GH-1234 diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md index 1d41099..345af6d 100644 --- a/.github/SUPPORT.md +++ b/.github/SUPPORT.md @@ -2,4 +2,4 @@ Terraform is a mature project with a growing community. There are active, dedicated people willing to help you through various mediums. -Take a look at those mediums listed at https://www.terraform.io/community.html +Take a look at those mediums listed at diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 664f688..49c39a6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,4 +39,4 @@ jobs: args: release --clean env: GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..602a42c --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,8 @@ +MD010: false +MD013: false +MD033: false +MD003: false +MD045: false +MD041: false +MD025: false +MD040: false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..a935fe8 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,46 @@ +repos: + - repo: https://github.com/dnephin/pre-commit-golang + rev: v0.5.1 + hooks: + - id: go-fmt + name: Format Go code + - id: go-vet + name: Verify Go code + - id: golangci-lint + name: Run golangci-lint + args: + - --exclude + - "Error return value of .(d.Set). is not checked" + + - repo: https://github.com/antonbabenko/pre-commit-terraform + rev: v1.83.5 + hooks: + - id: terraform_fmt + name: Format Terraform code + - id: terraform_validate + name: Validate Terraform code + - id: terraform_tflint + name: Lint Terraform code + + - repo: https://github.com/igorshubovych/markdownlint-cli + rev: v0.37.0 + hooks: + - id: markdownlint + name: Lint Markdown files + args: [--config=.markdownlint.yaml] + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: trailing-whitespace + name: Trim trailing whitespace + - id: end-of-file-fixer + name: Fix end of files + - id: check-yaml + name: Check YAML files + - id: mixed-line-ending + name: Fix line endings + - id: check-merge-conflict + name: Check for merge conflicts + - id: detect-private-key + name: Detect private keys diff --git a/README.md b/README.md index dcd6ac8..35b6870 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ Terraform provider for managing your Cloudsmith resources. Requirements ------------ -- [Terraform](https://www.terraform.io/downloads.html) >= 0.12.x -- [Go](https://golang.org/doc/install) >= 1.13 (to build the provider plugin) +- [Terraform](https://www.terraform.io/downloads.html) >= 0.12.x +- [Go](https://golang.org/doc/install) >= 1.13 (to build the provider plugin) Building The Provider --------------------- @@ -17,14 +17,14 @@ Building The Provider Clone repository: ```sh -$ git clone git@github.com:cloudsmith-io/terraform-provider-cloudsmith +git clone git@github.com:cloudsmith-io/terraform-provider-cloudsmith ``` Enter the provider directory and build the provider: ```sh -$ cd terraform-provider-cloudsmith -$ go build +cd terraform-provider-cloudsmith +go build ``` Using the provider @@ -61,7 +61,6 @@ resource "cloudsmith_entitlement" "my_entitlement" { } ``` - Retrieve a list of packages from a repository ``` @@ -95,7 +94,7 @@ Testing the Provider In order to test the provider, you can run `go test`. ```sh -$ go test -v ./... +go test -v ./... ``` In order to run the full suite of Acceptance tests, you'll need a paid Cloudsmith account. @@ -109,14 +108,14 @@ You'll also need to set a few environment variables: *Note:* Acceptance tests create real resources, and may cost money to run. ```sh -$ export TF_ACC=1 -$ export CLOUDSMITH_API_KEY=mykey -$ export CLOUDSMITH_NAMESPACE=mynamespace -$ go test -v ./... +export TF_ACC=1 +export CLOUDSMITH_API_KEY=mykey +export CLOUDSMITH_NAMESPACE=mynamespace +go test -v ./... ``` If needed, you can also run individual tests with the `-run` flag: ```sh -$ go test -v -run=TestAccEntitlement_basic ./... +go test -v -run=TestAccEntitlement_basic ./... ``` diff --git a/docs/data-sources/entitlement_list.md b/docs/data-sources/entitlement_list.md index c35fe48..6d11c85 100644 --- a/docs/data-sources/entitlement_list.md +++ b/docs/data-sources/entitlement_list.md @@ -1,4 +1,5 @@ # Entitlement Tokens Data Source + The `entitlement_tokens` data source allows for retrieval of a list of entitlement tokens within a given repository. ## Example Usage @@ -80,4 +81,4 @@ The following attribute is additionally exported: * `updated_by_url` - URL for the user who updated the entitlement token. * `usage` - The usage associated with the token. * `user` - The user associated with the token. - * `user_url` - URL for the user associated with the token. \ No newline at end of file + * `user_url` - URL for the user associated with the token. diff --git a/docs/data-sources/organization_list_org_memebrs.md b/docs/data-sources/organization_list_org_memebrs.md index 3509ad1..5edea01 100644 --- a/docs/data-sources/organization_list_org_memebrs.md +++ b/docs/data-sources/organization_list_org_memebrs.md @@ -38,4 +38,4 @@ The following attribute is additionally exported: * `last_login_method` - The method used by the member for the last login. * `role` - The role of the member within the organization. * `user` - The username of the member. - * `user_id` - The unique identifier of the member. \ No newline at end of file + * `user_id` - The unique identifier of the member. diff --git a/docs/data-sources/organization_member_details.md b/docs/data-sources/organization_member_details.md index 15e6e9a..9d3a49c 100644 --- a/docs/data-sources/organization_member_details.md +++ b/docs/data-sources/organization_member_details.md @@ -39,4 +39,4 @@ The following attribute is additionally exported: * `user_id` - The ID of the user (string). * `user_name` - The username of the user (string). * `user_url` - The URL of the user's profile (uri). -* `visibility` - The visibility of the member's profile. Defaults to "Public" and can be one of the following: "Public", "Private" (string). \ No newline at end of file +* `visibility` - The visibility of the member's profile. Defaults to "Public" and can be one of the following: "Public", "Private" (string). diff --git a/docs/data-sources/package.md b/docs/data-sources/package.md index 8d0b6ba..de188e9 100644 --- a/docs/data-sources/package.md +++ b/docs/data-sources/package.md @@ -34,29 +34,29 @@ data "cloudsmith_package" "test" { ## Argument Reference -- `namespace` (Required): The namespace of the package. -- `repository` (Required): The repository of the package. -- `identifier` (Required): The identifier for the package. -- `download` (Optional): If set to true, the package will be downloaded. Defaults to false. If set to false, the CDN URL will be available in the `output_path`. -- `download_dir` (Optional): The directory where the file will be downloaded to. If not set and `download` is set to `true`, it will default to the operating system's default temporary directory and save the file there. -- `ignore_checksums` (Optional): If set to `true`, any mismatched checksum from our API and local check will be ignored and download the package if `download` is set to `true`. +- `namespace` (Required): The namespace of the package. +- `repository` (Required): The repository of the package. +- `identifier` (Required): The identifier for the package. +- `download` (Optional): If set to true, the package will be downloaded. Defaults to false. If set to false, the CDN URL will be available in the `output_path`. +- `download_dir` (Optional): The directory where the file will be downloaded to. If not set and `download` is set to `true`, it will default to the operating system's default temporary directory and save the file there. +- `ignore_checksums` (Optional): If set to `true`, any mismatched checksum from our API and local check will be ignored and download the package if `download` is set to `true`. ## Attribute Reference -- `cdn_url`: The URL of the package to download. This attribute is computed and available only when the `download` argument is set to `false`. -- `checksum_md5`: MD5 hash of the downloaded package. If `download` is set to `false`, the checksum is returned from the package API instead. -- `checksum_sha1`: SHA1 hash of the downloaded package.If `download` is set to `false`, the checksum is returned from the package API instead. -- `checksum_sha256`: SHA256 hash of the downloaded package.If `download` is set to `false`, the checksum is returned from the package API instead. -- `checksum_sha512`: SHA512 hash of the downloaded package.If `download` is set to `false`, the checksum is returned from the package API instead. -- `format`: The format of the package. -- `is_sync_awaiting`: Indicates whether the package is awaiting synchronization. -- `is_sync_completed`: Indicates whether the package synchronization has completed. -- `is_sync_failed`: Indicates whether the package synchronization has failed. -- `is_sync_in_flight`: Indicates whether the package synchronization is currently in-flight. -- `is_sync_in_progress`: Indicates whether the package synchronization is currently in-progress. -- `name`: The name of the package. -- `output_path`: The location of the package. If the `download` argument is set to `true`, this will provide the path where the package is downloaded. -- `output_directory`: The directory where the package is downloaded. -- `slug`: The public unique identifier for the package. -- `slug_perm`: The slug_perm that immutably identifies the package. -- `version`: The version of the package. \ No newline at end of file +- `cdn_url`: The URL of the package to download. This attribute is computed and available only when the `download` argument is set to `false`. +- `checksum_md5`: MD5 hash of the downloaded package. If `download` is set to `false`, the checksum is returned from the package API instead. +- `checksum_sha1`: SHA1 hash of the downloaded package.If `download` is set to `false`, the checksum is returned from the package API instead. +- `checksum_sha256`: SHA256 hash of the downloaded package.If `download` is set to `false`, the checksum is returned from the package API instead. +- `checksum_sha512`: SHA512 hash of the downloaded package.If `download` is set to `false`, the checksum is returned from the package API instead. +- `format`: The format of the package. +- `is_sync_awaiting`: Indicates whether the package is awaiting synchronization. +- `is_sync_completed`: Indicates whether the package synchronization has completed. +- `is_sync_failed`: Indicates whether the package synchronization has failed. +- `is_sync_in_flight`: Indicates whether the package synchronization is currently in-flight. +- `is_sync_in_progress`: Indicates whether the package synchronization is currently in-progress. +- `name`: The name of the package. +- `output_path`: The location of the package. If the `download` argument is set to `true`, this will provide the path where the package is downloaded. +- `output_directory`: The directory where the package is downloaded. +- `slug`: The public unique identifier for the package. +- `slug_perm`: The slug_perm that immutably identifies the package. +- `version`: The version of the package. diff --git a/docs/data-sources/package_list.md b/docs/data-sources/package_list.md index 895ad99..d0b45e6 100644 --- a/docs/data-sources/package_list.md +++ b/docs/data-sources/package_list.md @@ -45,4 +45,3 @@ All of the argument attributes are also exported as result attributes. The following attribute is additionally exported: * `packages` - A list of `package` entries as discovered by the data source. - diff --git a/docs/data-sources/repository_privileges.md b/docs/data-sources/repository_privileges.md index 522dca3..d489b85 100644 --- a/docs/data-sources/repository_privileges.md +++ b/docs/data-sources/repository_privileges.md @@ -6,17 +6,17 @@ The `cloudsmith_repository_privileges` data source allows you to retrieve inform ```hcl provider "cloudsmith" { - api_key = "my-api-key" + api_key = "my-api-key" } resource "cloudsmith_repository" "test" { - name = "terraform-acc-test-privileges" - namespace = "" + name = "terraform-acc-test-privileges" + namespace = "" } data "cloudsmith_repository_privileges" "test_data" { - organization = cloudsmith_repository.test.namespace - repository = cloudsmith_repository.test.slug + organization = cloudsmith_repository.test.namespace + repository = cloudsmith_repository.test.slug } ``` @@ -30,13 +30,13 @@ data "cloudsmith_repository_privileges" "test_data" { The following attributes are available: * service: A set containing privileges information for service accounts. - * privilege: The privilege level (Admin, Write, Read). - * slug: The unique identifier for the service account. + * privilege: The privilege level (Admin, Write, Read). + * slug: The unique identifier for the service account. * team: A set containing privileges information for teams. - * privilege: The privilege level (Admin, Write, Read). - * slug: The unique identifier for the team. + * privilege: The privilege level (Admin, Write, Read). + * slug: The unique identifier for the team. * user: A set containing privileges information for users. - * privilege: The privilege level (Admin, Write, Read). - * slug: The unique identifier for the user. + * privilege: The privilege level (Admin, Write, Read). + * slug: The unique identifier for the user. diff --git a/docs/resources/license_policy.md b/docs/resources/license_policy.md index c7ad859..a4e0622 100644 --- a/docs/resources/license_policy.md +++ b/docs/resources/license_policy.md @@ -20,7 +20,7 @@ resource "cloudsmith_license_policy" "my_license_policy" { description = "My license policy" spdx_identifiers = ["Apache-2.0"] on_violation_quarantine = true - package_query_string = "format:python AND downloads:>50" + package_query_string = "format:python AND downloads:>50" organization = "my-organization" } ``` diff --git a/docs/resources/oidc.md b/docs/resources/oidc.md index 31fcb31..fbc6893 100644 --- a/docs/resources/oidc.md +++ b/docs/resources/oidc.md @@ -48,4 +48,4 @@ This resource can be imported using the organization slug and the OIDC slug_perm ```shell terraform import cloudsmith_oidc.my_oidc my-organization.my-oidc-slug-perm -``` \ No newline at end of file +``` diff --git a/docs/resources/package_deny_policy.md b/docs/resources/package_deny_policy.md index da414b8..d3c6e65 100644 --- a/docs/resources/package_deny_policy.md +++ b/docs/resources/package_deny_policy.md @@ -40,4 +40,4 @@ The following attributes are exported: - `description` - The description of the package deny policy. - `package_query` - The query used to match the packages to be blocked. - `enabled` - Whether the package deny policy is enabled. -- `namespace` - The namespace where package deny policy is managed \ No newline at end of file +- `namespace` - The namespace where package deny policy is managed diff --git a/docs/resources/repository_privileges.md b/docs/resources/repository_privileges.md index 2a0ac0f..7de92b7 100644 --- a/docs/resources/repository_privileges.md +++ b/docs/resources/repository_privileges.md @@ -25,38 +25,38 @@ resource "cloudsmith_repository" "my_repository" { } resource "cloudsmith_team" "my_team" { - organization = data.cloudsmith_organization.my_organization.slug_perm - name = "My Team" + organization = data.cloudsmith_organization.my_organization.slug_perm + name = "My Team" } resource "cloudsmith_team" "my_other_team" { - organization = data.cloudsmith_organization.my_organization.slug_perm - name = "My Other Team" + organization = data.cloudsmith_organization.my_organization.slug_perm + name = "My Other Team" } resource "cloudsmith_service" "my_service" { - name = "My Service" - organization = data.cloudsmith_organization.my_organization.slug_perm + name = "My Service" + organization = data.cloudsmith_organization.my_organization.slug_perm } resource "cloudsmith_repository_privileges" "privs" { organization = data.cloudsmith_organization.my_organization.slug repository = cloudsmith_repository.my_repository.slug - service { - privilege = "Write" - slug = cloudsmith_service.my_service.slug - } + service { + privilege = "Write" + slug = cloudsmith_service.my_service.slug + } - team { - privilege = "Write" - slug = cloudsmith_team.my_team.slug - } + team { + privilege = "Write" + slug = cloudsmith_team.my_team.slug + } - team { - privilege = "Read" - slug = cloudsmith_team.my_other_team.slug - } + team { + privilege = "Read" + slug = cloudsmith_team.my_other_team.slug + } user { privilege = "Read" @@ -72,14 +72,14 @@ The following arguments are supported: * `organization` - (Required) Organization to which this repository belongs. * `repository` - (Required) Repository to which these privileges apply. * `service` - (Optional) Variable number of blocks containing service accounts that should have repository privileges. - * `privilege` - (Required) The service's privilege level in the repository. Must be one of `Admin`, `Write`, or `Read`. - * `slug` - (Required) The slug/identifier of the service. + * `privilege` - (Required) The service's privilege level in the repository. Must be one of `Admin`, `Write`, or `Read`. + * `slug` - (Required) The slug/identifier of the service. * `team` - (Optional) Variable number of blocks containing teams that should have repository privileges. - * `privilege` - (Required) The team's privilege level in the repository. Must be one of `Admin`, `Write`, or `Read`. - * `slug` - (Required) The slug/identifier of the team. + * `privilege` - (Required) The team's privilege level in the repository. Must be one of `Admin`, `Write`, or `Read`. + * `slug` - (Required) The slug/identifier of the team. * `user` - (Optional) Variable number of blocks containing users that should have repository privileges. - * `privilege` - (Required) The user's privilege level in the repository. Must be one of `Admin`, `Write`, or `Read`. - * `slug` - (Required) The slug/identifier of the user. + * `privilege` - (Required) The user's privilege level in the repository. Must be one of `Admin`, `Write`, or `Read`. + * `slug` - (Required) The slug/identifier of the user. ## Import diff --git a/docs/resources/repository_retention.md b/docs/resources/repository_retention.md index e023011..75afb3a 100644 --- a/docs/resources/repository_retention.md +++ b/docs/resources/repository_retention.md @@ -57,4 +57,4 @@ This resource can be imported using the namespace and repository slug: ```shell terraform import cloudsmith_repository_retention_rule.retention_rule my-namespace-slug.my-repository -``` \ No newline at end of file +``` diff --git a/docs/resources/service.md b/docs/resources/service.md index 354c992..ca16eff 100644 --- a/docs/resources/service.md +++ b/docs/resources/service.md @@ -8,25 +8,25 @@ See [help.cloudsmith.io](https://help.cloudsmith.io/docs/service-accounts) for f ```hcl provider "cloudsmith" { - api_key = "my-api-key" + api_key = "my-api-key" } data "cloudsmith_organization" "my_org" { - slug = "my-organization" + slug = "my-organization" } resource "cloudsmith_team" "my_team" { - organization = data.cloudsmith_organization.my_org.slug - name = "My Team" + organization = data.cloudsmith_organization.my_org.slug + name = "My Team" } resource "cloudsmith_service" "my_service" { - name = "My Service" - organization = data.cloudsmith_organization.my_org.slug + name = "My Service" + organization = data.cloudsmith_organization.my_org.slug - team { - slug = cloudsmith_team.my_team.slug - } + team { + slug = cloudsmith_team.my_team.slug + } } ``` @@ -39,8 +39,8 @@ The following arguments are supported: * `organization` - (Required) Organization to which this service belongs. * `role` - (Optional) The service's role in the organization. If defined, must be one of `Member` or `Manager`. * `team` - (Optional) Variable number of blocks containing team assignments for this service. - * `role` - (Optional) The service's role in the team. If defined, must be one of `Member` or `Manager`. - * `slug` - (Required) The team the service should be added to. + * `role` - (Optional) The service's role in the team. If defined, must be one of `Member` or `Manager`. + * `slug` - (Required) The team the service should be added to. * `store_api_key` - (Optional) The service's API key to be returned in state. Defaults to `true`. If set to `false`, the "key" value is replaced with `**redacted**`. **NOTE:** This will only be applied to newly created service accounts, **this won't take effect for existing service accounts**. ## Attribute Reference diff --git a/docs/resources/vulnerability_policy.md b/docs/resources/vulnerability_policy.md index b39f8f0..5c5e463 100644 --- a/docs/resources/vulnerability_policy.md +++ b/docs/resources/vulnerability_policy.md @@ -21,7 +21,7 @@ resource "cloudsmith_vulnerability_policy" "my_vulnerability_policy" { min_severity = "Medium" on_violation_quarantine = true allow_unknown_severity = false - package_query_string = "format:python AND downloads:>50" + package_query_string = "format:python AND downloads:>50" organization = "my-organization" } ``` diff --git a/docs/resources/webhook.md b/docs/resources/webhook.md index e0c6b26..5a26d27 100644 --- a/docs/resources/webhook.md +++ b/docs/resources/webhook.md @@ -26,19 +26,19 @@ resource "cloudsmith_webhook" "my_webhook" { namespace = cloudsmith_repository.my_repository.namespace repository = cloudsmith_repository.my_repository.slug_perm - events = ["package.created", "package.deleted"] - request_body_format = "Handlebars Template" - target_url = "https://example.com" - - template { - event = "package.created" - template = "created: {{data.name}}: {{data.version}}" - } - - template { - event = "package.deleted" - template = "deleted: {{data.name}}: {{data.version}}" - } + events = ["package.created", "package.deleted"] + request_body_format = "Handlebars Template" + target_url = "https://example.com" + + template { + event = "package.created" + template = "created: {{data.name}}: {{data.version}}" + } + + template { + event = "package.deleted" + template = "deleted: {{data.name}}: {{data.version}}" + } } ``` @@ -57,8 +57,8 @@ resource "cloudsmith_webhook" "my_webhook" { * `signature_key` - (Optional) The value for the signature key - This is used to generate an HMAC-based hex digest of the request body, which we send as the X-Cloudsmith-Signature header so that you can ensure that the request wasn't modified by a malicious party (note: this is treated as a passphrase and is encrypted when we store it). * `target_url` - (Required) The destination URL that webhook payloads will be POST'ed to. * `template` - (Optional) Variable number of blocks containing templates used to render webhook content before sending. - * `event` - (Required) The event for which this template will be applied. - * `template` - (Required) The contents of the template to be rendered. + * `event` - (Required) The event for which this template will be applied. + * `template` - (Required) The contents of the template to be rendered. * `is_active` - (Optional) If enabled, SSL certificates is verified when webhooks are sent. It's recommended to leave this enabled as not verifying the integrity of SSL certificates leaves you susceptible to Man-in-the-Middle (MITM) attacks. ## Attribute Reference diff --git a/examples/flat-example/README.md b/examples/flat-example/README.md index ef2c570..ef01eef 100644 --- a/examples/flat-example/README.md +++ b/examples/flat-example/README.md @@ -6,4 +6,4 @@ The example will also configures basic org-level settings like license policy, S ## Usage -In order to get started, supply your api key and org name in `global-variables.tf` file and run `terraform apply` against it. \ No newline at end of file +In order to get started, supply your api key and org name in `global-variables.tf` file and run `terraform apply` against it. diff --git a/examples/flat-example/global-variables.tf b/examples/flat-example/global-variables.tf index cc938a6..48d4449 100644 --- a/examples/flat-example/global-variables.tf +++ b/examples/flat-example/global-variables.tf @@ -27,5 +27,3 @@ variable "geopip_allow_countries" { type = list(string) default = ["US", "GB", "DE"] } - - diff --git a/examples/flat-example/org-deny-policy.tf b/examples/flat-example/org-deny-policy.tf index 413c522..7f7428e 100644 --- a/examples/flat-example/org-deny-policy.tf +++ b/examples/flat-example/org-deny-policy.tf @@ -1,6 +1,6 @@ resource "cloudsmith_package_deny_policy" "left_pad_policy" { - name = "Deny left-pad" - description = "Deny left-pad versions greater than 1.1.2" - package_query = "format:npm AND name:left-pad AND version:>1.1.2" - namespace = data.cloudsmith_organization.org-demo.slug -} \ No newline at end of file + name = "Deny left-pad" + description = "Deny left-pad versions greater than 1.1.2" + package_query = "format:npm AND name:left-pad AND version:>1.1.2" + namespace = data.cloudsmith_organization.org-demo.slug +} diff --git a/examples/flat-example/org-license-policy.tf b/examples/flat-example/org-license-policy.tf index 17abc2b..cc049fa 100644 --- a/examples/flat-example/org-license-policy.tf +++ b/examples/flat-example/org-license-policy.tf @@ -1,17 +1,17 @@ resource "cloudsmith_license_policy" "apache-python-policy" { - name = "Example License Policy" - description = "Apache 2 License Policy for Python packages" - spdx_identifiers = ["Apache-2.0"] - on_violation_quarantine = true - package_query_string = "format:python AND downloads:>50" - organization = data.cloudsmith_organization.org-demo.slug + name = "Example License Policy" + description = "Apache 2 License Policy for Python packages" + spdx_identifiers = ["Apache-2.0"] + on_violation_quarantine = true + package_query_string = "format:python AND downloads:>50" + organization = data.cloudsmith_organization.org-demo.slug } resource "cloudsmith_license_policy" "mit-npm-policy" { - name = "Example License Policy" - description = "MIT License Policy for Python packages" - spdx_identifiers = ["MIT"] - on_violation_quarantine = true - package_query_string = "format:npm" - organization = data.cloudsmith_organization.org-demo.slug -} \ No newline at end of file + name = "Example License Policy" + description = "MIT License Policy for Python packages" + spdx_identifiers = ["MIT"] + on_violation_quarantine = true + package_query_string = "format:npm" + organization = data.cloudsmith_organization.org-demo.slug +} diff --git a/examples/flat-example/org-oidc-config.tf b/examples/flat-example/org-oidc-config.tf index e12971a..9b65306 100644 --- a/examples/flat-example/org-oidc-config.tf +++ b/examples/flat-example/org-oidc-config.tf @@ -1,10 +1,10 @@ resource "cloudsmith_oidc" "devops-oidc" { - namespace = data.cloudsmith_organization.org-demo.slug - name = "OIDC-DEMO" - enabled = true - provider_url = "https://token.actions.githubusercontent.com" - service_accounts = [cloudsmith_service.production-service.slug] - claims = { - "repository" = "Owner/GitHubRepoName" - } -} \ No newline at end of file + namespace = data.cloudsmith_organization.org-demo.slug + name = "OIDC-DEMO" + enabled = true + provider_url = "https://token.actions.githubusercontent.com" + service_accounts = [cloudsmith_service.production-service.slug] + claims = { + "repository" = "Owner/GitHubRepoName" + } +} diff --git a/examples/flat-example/org-saml-group.tf b/examples/flat-example/org-saml-group.tf index 829fea8..d5819cc 100644 --- a/examples/flat-example/org-saml-group.tf +++ b/examples/flat-example/org-saml-group.tf @@ -1,15 +1,15 @@ resource "cloudsmith_saml" "owners_mapping" { organization = data.cloudsmith_organization.org-demo.slug - idp_key = "administrators" - idp_value = "administrators" - role = "Manager" - team = "owners" + idp_key = "administrators" + idp_value = "administrators" + role = "Manager" + team = "owners" } resource "cloudsmith_saml" "developers_mapping" { organization = data.cloudsmith_organization.org-demo.slug - idp_key = "interns" - idp_value = "interns" - role = "Member" - team = resource.cloudsmith_team.interns.slug -} \ No newline at end of file + idp_key = "interns" + idp_value = "interns" + role = "Member" + team = resource.cloudsmith_team.interns.slug +} diff --git a/examples/flat-example/provider.tf b/examples/flat-example/provider.tf index e89a715..ecae6f6 100644 --- a/examples/flat-example/provider.tf +++ b/examples/flat-example/provider.tf @@ -1,11 +1,13 @@ +# tflint-ignore-file: terraform_required_version, terraform_required_providers + terraform { - required_providers { - cloudsmith = { - source = "cloudsmith-io/cloudsmith" - } + required_providers { + cloudsmith = { + source = "cloudsmith-io/cloudsmith" } + } } provider "cloudsmith" { api_key = var.api_key -} \ No newline at end of file +} diff --git a/examples/flat-example/repo-devops.tf b/examples/flat-example/repo-devops.tf index 0cf08a2..e226a4f 100644 --- a/examples/flat-example/repo-devops.tf +++ b/examples/flat-example/repo-devops.tf @@ -27,7 +27,7 @@ resource "cloudsmith_repository_privileges" "devops-privs" { } resource "cloudsmith_repository_geo_ip_rules" "devops-geoip" { - repository = cloudsmith_repository.devops.slug - namespace = data.cloudsmith_organization.org-demo.slug + repository = cloudsmith_repository.devops.slug + namespace = data.cloudsmith_organization.org-demo.slug country_code_allow = var.geopip_allow_countries -} \ No newline at end of file +} diff --git a/examples/flat-example/repo-oidc-demo.tf b/examples/flat-example/repo-oidc-demo.tf index fd36336..55cdcc2 100644 --- a/examples/flat-example/repo-oidc-demo.tf +++ b/examples/flat-example/repo-oidc-demo.tf @@ -19,4 +19,4 @@ resource "cloudsmith_repository_privileges" "oidc_demo-privs" { privilege = "Write" slug = cloudsmith_service.developer-service.slug } -} \ No newline at end of file +} diff --git a/examples/iterative-example/README.md b/examples/iterative-example/README.md index 88b3530..b8e3ec7 100644 --- a/examples/iterative-example/README.md +++ b/examples/iterative-example/README.md @@ -10,11 +10,11 @@ shares many attributes with the others, but changes slightly based on their indi * Creates a Developers team which gets write permission on the Development repository * Configures DockerHub and Chainguard upstreams on each repository * Configures a Vulnerablity policy that blocks high severity vulnerabilities. -* Configures a license policy that blocks AGPL licensed packages. +* Configures a license policy that blocks AGPL licensed packages. ## Usage To get started, supply your API key and org name in `global-variables.tf` file. Run `terraform init` and then run `terraform apply` to execute the plan. -Configuration can be done in the `terraform.tfvars` file. \ No newline at end of file +Configuration can be done in the `terraform.tfvars` file. diff --git a/examples/iterative-example/global-variables.tf b/examples/iterative-example/global-variables.tf index f933455..20558d6 100644 --- a/examples/iterative-example/global-variables.tf +++ b/examples/iterative-example/global-variables.tf @@ -13,19 +13,19 @@ variable "default_storage_region" { } variable "chainguard_api_user" { - type = string - default = "YOUR-CHAINGUARD-API-USER" + type = string + default = "YOUR-CHAINGUARD-API-USER" } variable "chainguard_api_secret" { - type = string - default = "YOUR-CHAINGUARD-API-SECRET" + type = string + default = "YOUR-CHAINGUARD-API-SECRET" } variable "repositories" { type = map(object({ add_developers = optional(bool) - oidc_claims = optional(map(string)) + oidc_claims = optional(map(string)) })) description = "A map of repositories with their configurations." default = { @@ -39,8 +39,8 @@ variable "repositories" { } variable "oidc_claims" { - type = map(string) - default = { - "repository" = "Owner/GitHubRepoName" - } + type = map(string) + default = { + "repository" = "Owner/GitHubRepoName" + } } diff --git a/examples/iterative-example/license-policy.tf b/examples/iterative-example/license-policy.tf index ab0b4a5..a55c5a0 100644 --- a/examples/iterative-example/license-policy.tf +++ b/examples/iterative-example/license-policy.tf @@ -1,7 +1,7 @@ resource "cloudsmith_license_policy" "agpl-policy" { - name = "Block AGPL" - description = "Block AGPL licensed packages" - spdx_identifiers = ["AGPL-1.0", "AGPL-1.0-only", "AGPL-1.0-or-later", "AGPL-3.0", "AGPL-3.0-only", "AGPL-3.0-or-later"] - on_violation_quarantine = true - organization = data.cloudsmith_organization.cloudsmith-org.slug -} \ No newline at end of file + name = "Block AGPL" + description = "Block AGPL licensed packages" + spdx_identifiers = ["AGPL-1.0", "AGPL-1.0-only", "AGPL-1.0-or-later", "AGPL-3.0", "AGPL-3.0-only", "AGPL-3.0-or-later"] + on_violation_quarantine = true + organization = data.cloudsmith_organization.cloudsmith-org.slug +} diff --git a/examples/iterative-example/oidc-config.tf b/examples/iterative-example/oidc-config.tf index 0283af8..d0bd455 100644 --- a/examples/iterative-example/oidc-config.tf +++ b/examples/iterative-example/oidc-config.tf @@ -1,9 +1,9 @@ resource "cloudsmith_oidc" "org-oidc" { - for_each = var.repositories - namespace = data.cloudsmith_organization.cloudsmith-org.slug - name = "Github OIDC - ${each.key}" - enabled = true - provider_url = "https://token.actions.githubusercontent.com" - service_accounts = [cloudsmith_service.ci-service[each.key].slug] - claims = (each.value.oidc_claims != null) ? each.value.oidc_claims : var.oidc_claims -} \ No newline at end of file + for_each = var.repositories + namespace = data.cloudsmith_organization.cloudsmith-org.slug + name = "Github OIDC - ${each.key}" + enabled = true + provider_url = "https://token.actions.githubusercontent.com" + service_accounts = [cloudsmith_service.ci-service[each.key].slug] + claims = (each.value.oidc_claims != null) ? each.value.oidc_claims : var.oidc_claims +} diff --git a/examples/iterative-example/provider.tf b/examples/iterative-example/provider.tf index e89a715..ecae6f6 100644 --- a/examples/iterative-example/provider.tf +++ b/examples/iterative-example/provider.tf @@ -1,11 +1,13 @@ +# tflint-ignore-file: terraform_required_version, terraform_required_providers + terraform { - required_providers { - cloudsmith = { - source = "cloudsmith-io/cloudsmith" - } + required_providers { + cloudsmith = { + source = "cloudsmith-io/cloudsmith" } + } } provider "cloudsmith" { api_key = var.api_key -} \ No newline at end of file +} diff --git a/examples/iterative-example/repositories.tf b/examples/iterative-example/repositories.tf index 336ae99..fb67c38 100644 --- a/examples/iterative-example/repositories.tf +++ b/examples/iterative-example/repositories.tf @@ -1,12 +1,12 @@ resource "cloudsmith_repository" "repositories" { - for_each = var.repositories - description = "${title(each.key)} repository" - name = "${each.key}" - namespace = data.cloudsmith_organization.cloudsmith-org.slug_perm - slug = "${each.key}" - repository_type = "Private" - storage_region = var.default_storage_region - user_entitlements_enabled = false + for_each = var.repositories + description = "${title(each.key)} repository" + name = each.key + namespace = data.cloudsmith_organization.cloudsmith-org.slug_perm + slug = each.key + repository_type = "Private" + storage_region = var.default_storage_region + user_entitlements_enabled = false } diff --git a/examples/iterative-example/teams.tf b/examples/iterative-example/teams.tf index 587a871..97519be 100644 --- a/examples/iterative-example/teams.tf +++ b/examples/iterative-example/teams.tf @@ -1,4 +1,4 @@ resource "cloudsmith_team" "developers" { organization = data.cloudsmith_organization.cloudsmith-org.slug_perm name = "Developers" -} \ No newline at end of file +} diff --git a/examples/iterative-example/terraform.tfvars b/examples/iterative-example/terraform.tfvars index c8fa160..9d0b00c 100644 --- a/examples/iterative-example/terraform.tfvars +++ b/examples/iterative-example/terraform.tfvars @@ -1,14 +1,14 @@ repositories = { - "development": { - "add_developers": true + "development" : { + "add_developers" : true }, - "staging": { - "add_developers": false + "staging" : { + "add_developers" : false }, - "production": { - "add_developers": false - "oidc_claims": { + "production" : { + "add_developers" : false + "oidc_claims" : { "repository" = "Owner/ProductionGithubRepoName" } } -} \ No newline at end of file +} diff --git a/examples/iterative-example/upstreams.tf b/examples/iterative-example/upstreams.tf index d892a0b..994dc87 100644 --- a/examples/iterative-example/upstreams.tf +++ b/examples/iterative-example/upstreams.tf @@ -36,4 +36,4 @@ resource "cloudsmith_repository_upstream" "dockerhub" { upstream_url = "https://index.docker.io" mode = "Cache and Proxy" priority = 1 -} \ No newline at end of file +} diff --git a/examples/iterative-example/vulnerability-policy.tf b/examples/iterative-example/vulnerability-policy.tf index 48e015b..97e720e 100644 --- a/examples/iterative-example/vulnerability-policy.tf +++ b/examples/iterative-example/vulnerability-policy.tf @@ -6,4 +6,4 @@ resource "cloudsmith_vulnerability_policy" "container-policy-test" { allow_unknown_severity = true package_query_string = "format:docker" organization = data.cloudsmith_organization.cloudsmith-org.slug -} \ No newline at end of file +} diff --git a/go.mod b/go.mod index 45bf45c..34a69a6 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/cloudsmith-io/terraform-provider-cloudsmith go 1.19 require ( - github.com/cloudsmith-io/cloudsmith-api-go v0.0.40 + github.com/cloudsmith-io/cloudsmith-api-go v0.0.41 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1 github.com/samber/lo v1.36.0 diff --git a/go.sum b/go.sum index 33dbef1..4b29be2 100644 --- a/go.sum +++ b/go.sum @@ -6,39 +6,21 @@ github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= -github.com/ProtonMail/go-crypto v1.1.0-alpha.5-proton h1:KVBEgU3CJpmzLChnLiSuEyCuhGhcMt3eOST+7A+ckto= -github.com/ProtonMail/go-crypto v1.1.0-alpha.5-proton/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= -github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I= github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= -github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= -github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE= -github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU= -github.com/cloudsmith-io/cloudsmith-api-go v0.0.35 h1:L3vzoZcYrYQgbuIGygwCuAgkkjcQoEl8cdMGyWeIl1U= -github.com/cloudsmith-io/cloudsmith-api-go v0.0.35/go.mod h1:xHTDgU8TyMXiWUZdn2OQR7AaZdz9M5SrNenyQU44zGQ= -github.com/cloudsmith-io/cloudsmith-api-go v0.0.36 h1:QWN/UQ3xi60/aNE6Fpqb0Q2ITbSYk3kSW9UsvdiWSsU= -github.com/cloudsmith-io/cloudsmith-api-go v0.0.36/go.mod h1:xHTDgU8TyMXiWUZdn2OQR7AaZdz9M5SrNenyQU44zGQ= -github.com/cloudsmith-io/cloudsmith-api-go v0.0.37 h1:cWbThERyAmZIyuVXmEWpDAR/EQiRrrkYuVxx7wP+wpI= -github.com/cloudsmith-io/cloudsmith-api-go v0.0.37/go.mod h1:xHTDgU8TyMXiWUZdn2OQR7AaZdz9M5SrNenyQU44zGQ= -github.com/cloudsmith-io/cloudsmith-api-go v0.0.38 h1:9LvozmogNMZ7MAULrEyV8nWJv0BUbctB/WvplRBjUaU= -github.com/cloudsmith-io/cloudsmith-api-go v0.0.38/go.mod h1:xHTDgU8TyMXiWUZdn2OQR7AaZdz9M5SrNenyQU44zGQ= -github.com/cloudsmith-io/cloudsmith-api-go v0.0.39 h1:cS3EAOo7yZqrpudgceuvIRTlXyCbDGaJvKVuNIfSBOo= -github.com/cloudsmith-io/cloudsmith-api-go v0.0.39/go.mod h1:xHTDgU8TyMXiWUZdn2OQR7AaZdz9M5SrNenyQU44zGQ= -github.com/cloudsmith-io/cloudsmith-api-go v0.0.40 h1:9Ps/Uz5uswLS39l/0mHU2Ivc3Gqk0KORiPrZP3exs6I= -github.com/cloudsmith-io/cloudsmith-api-go v0.0.40/go.mod h1:xHTDgU8TyMXiWUZdn2OQR7AaZdz9M5SrNenyQU44zGQ= +github.com/cloudsmith-io/cloudsmith-api-go v0.0.41 h1:7bPbyD3FIN8PmmZQg43O/y8OTkFFZ2ZxcSbrMcdrjHE= +github.com/cloudsmith-io/cloudsmith-api-go v0.0.41/go.mod h1:xHTDgU8TyMXiWUZdn2OQR7AaZdz9M5SrNenyQU44zGQ= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -49,8 +31,6 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= -github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= @@ -78,8 +58,6 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -88,12 +66,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -104,16 +78,10 @@ github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUK github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= github.com/hashicorp/go-hclog v1.2.1 h1:YQsLlGDJgwhXFpucSPyVbCBviQtjlHv3jLTlp8YmtEw= github.com/hashicorp/go-hclog v1.2.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= -github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-plugin v1.4.6 h1:MDV3UrKQBM3du3G7MApDGvOsMYy3JQJ4exhSoKBAeVA= github.com/hashicorp/go-plugin v1.4.6/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= -github.com/hashicorp/go-plugin v1.6.1 h1:P7MR2UP6gNKGPp+y7EZw2kOiq4IR9WiqLvp0XOsVdwI= -github.com/hashicorp/go-plugin v1.6.1/go.mod h1:XPHFku2tFo3o3QKFgSYo+cghcUhw1NA1hZyMK0PWAw0= -github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= -github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -121,54 +89,28 @@ github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hc-install v0.4.0 h1:cZkRFr1WVa0Ty6x5fTvL1TuO1flul231rWkGH92oYYk= github.com/hashicorp/hc-install v0.4.0/go.mod h1:5d155H8EC5ewegao9A4PUTMNPZaq+TbOzkJJZ4vrXeI= -github.com/hashicorp/hc-install v0.7.0 h1:Uu9edVqjKQxxuD28mR5TikkKDd/p55S8vzPC1659aBk= -github.com/hashicorp/hc-install v0.7.0/go.mod h1:ELmmzZlGnEcqoUMKUuykHaPCIR1sYLYX+KSggWSKZuA= -github.com/hashicorp/hc-install v0.8.0 h1:LdpZeXkZYMQhoKPCecJHlKvUkQFixN/nvyR1CdfOLjI= -github.com/hashicorp/hc-install v0.8.0/go.mod h1:+MwJYjDfCruSD/udvBmRB22Nlkwwkwf5sAB6uTIhSaU= github.com/hashicorp/hcl/v2 v2.15.0 h1:CPDXO6+uORPjKflkWCCwoWc9uRp+zSIPcCQ+BrxV7m8= github.com/hashicorp/hcl/v2 v2.15.0/go.mod h1:JRmR89jycNkrrqnMmvPDMd56n1rQJ2Q6KocSLCMCXng= -github.com/hashicorp/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14= -github.com/hashicorp/hcl/v2 v2.21.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= -github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M= -github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/terraform-exec v0.17.3 h1:MX14Kvnka/oWGmIkyuyvL6POx25ZmKrjlaclkx3eErU= github.com/hashicorp/terraform-exec v0.17.3/go.mod h1:+NELG0EqQekJzhvikkeQsOAZpsw0cv/03rbeQJqscAI= -github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= -github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg= github.com/hashicorp/terraform-json v0.14.0 h1:sh9iZ1Y8IFJLx+xQiKHGud6/TSUCM0N8e17dKDpqV7s= github.com/hashicorp/terraform-json v0.14.0/go.mod h1:5A9HIWPkk4e5aeeXIBbkcOvaZbIYnAIkEyqP2pNSckM= -github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7orfb5Ltvec= -github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A= github.com/hashicorp/terraform-plugin-go v0.14.1 h1:cwZzPYla82XwAqpLhSzdVsOMU+6H29tczAwrB0z9Zek= github.com/hashicorp/terraform-plugin-go v0.14.1/go.mod h1:Bc/K6K26BQ2FHqIELPbpKtt2CzzbQou+0UQF3/0NsCQ= -github.com/hashicorp/terraform-plugin-go v0.23.0 h1:AALVuU1gD1kPb48aPQUjug9Ir/125t+AAurhqphJ2Co= -github.com/hashicorp/terraform-plugin-go v0.23.0/go.mod h1:1E3Cr9h2vMlahWMbsSEcNrOCxovCZhOOIXjFHbjc/lQ= github.com/hashicorp/terraform-plugin-log v0.7.0 h1:SDxJUyT8TwN4l5b5/VkiTIaQgY6R+Y2BQ0sRZftGKQs= github.com/hashicorp/terraform-plugin-log v0.7.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4= -github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= -github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1 h1:zHcMbxY0+rFO9gY99elV/XC/UnQVg7FhRCbj1i5b7vM= github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1/go.mod h1:+tNlb0wkfdsDJ7JEiERLz4HzM19HyiuIoGzTsM7rPpw= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 h1:kJiWGx2kiQVo97Y5IOGR4EMcZ8DtMswHhUuFibsCQQE= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0/go.mod h1:sl/UoabMc37HA6ICVMmGO+/0wofkVIRxf+BMb/dnoIg= github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c h1:D8aRO6+mTqHfLsK/BC3j5OAoogv1WLRWzY1AaTo3rBg= github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c/go.mod h1:Wn3Na71knbXc1G8Lh+yu/dQWWJeFQEpDeJMtWMtlmNI= -github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= -github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 h1:HKLsbzeOsfXmKNpr3GiT18XAblV0BjCbzL8KQAMZGa0= github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg= -github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= -github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= -github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -191,14 +133,9 @@ github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlW github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -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/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -207,8 +144,6 @@ github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJ github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= -github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -217,8 +152,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= -github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -226,10 +159,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/samber/lo v1.36.0 h1:4LaOxH1mHnbDGhTVE0i1z8v/lWaQW8AIfOD3HU4mSaw= github.com/samber/lo v1.36.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= -github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ= -github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= -github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= -github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= @@ -248,54 +177,29 @@ github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaU github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U= github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= -github.com/vmihailenco/msgpack/v4 v4.3.13 h1:A2wsiTbvp63ilDaWmsk2wjx6xZdxQOvpiNlKBGKKXKI= -github.com/vmihailenco/msgpack/v4 v4.3.13/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= -github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= -github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= -github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= github.com/zclconf/go-cty v1.12.1 h1:PcupnljUm9EIvbgSHQnHhUr3fO6oFmkOrvs2BAFNXXY= github.com/zclconf/go-cty v1.12.1/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA= -github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ= -github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 h1:O8uGbHCqlTp2P6QJSLmCojM4mN6UemYv8K+dCnmHmu0= golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= -golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -304,7 +208,6 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -312,22 +215,12 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -345,77 +238,34 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 h1:PDIOdWxZ8eRizhKa1AAvY53xsvLB1cWorMjslvY3VA8= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20240730163845-b1a4ccb954bf h1:OqdXDEakZCVtDiZTjcxfwbHPCT11ycCEsTKesBVKvyY= -google.golang.org/genproto v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:mCr1K1c8kX+1iSBREvU3Juo11CB+QOEWxbRS01wWl5M= -google.golang.org/genproto v0.0.0-20240805194559-2c9e96a0b5d4 h1:g+rQ3aqOyXK/0qwnC5TGUXnyIeipstP5SsniB9uPJ2c= -google.golang.org/genproto v0.0.0-20240805194559-2c9e96a0b5d4/go.mod h1:7uvplUBj4RjHAxIZ//98LzOvrQ04JBkaixRmCMI29hc= -google.golang.org/genproto v0.0.0-20240827150818-7e3bb234dfed h1:4C4dbrVFtfIp3GXJdMX1Sj25mahfn5DywOo65/2ISQ8= -google.golang.org/genproto v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:ICjniACoWvcDz8c8bOsHVKuuSGDJy1z5M4G0DM3HzTc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240725223205-93522f1f2a9f h1:RARaIm8pxYuxyNPbBQf5igT7XdOyCNtat1qAT2ZxjU4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240725223205-93522f1f2a9f/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf h1:liao9UHurZLtiEwBgT9LMOnKYsHze6eA6w1KQCMVN2Q= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240805194559-2c9e96a0b5d4 h1:OsSGQeIIsyOEOimVxLEIL4rwGcnrjOydQaiA2bOnZUM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240805194559-2c9e96a0b5d4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240823204242-4ba0660f739c h1:Kqjm4WpoWvwhMPcrAczoTyMySQmYa9Wy2iL6Con4zn8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240823204242-4ba0660f739c/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= -google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= -google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -428,8 +278,6 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From b674e6ef627658f7ca648297c5d716fc3221352f Mon Sep 17 00:00:00 2001 From: Ian Duffy Date: Fri, 29 Nov 2024 20:30:36 +0000 Subject: [PATCH 2/8] Adjust cloudsmith-api-go binding --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 34a69a6..fe3c4a3 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/cloudsmith-io/terraform-provider-cloudsmith go 1.19 require ( - github.com/cloudsmith-io/cloudsmith-api-go v0.0.41 + github.com/cloudsmith-io/cloudsmith-api-go v0.0.42-0.20241129202450-bd5381591ce5 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1 github.com/samber/lo v1.36.0 diff --git a/go.sum b/go.sum index 4b29be2..35a0aaf 100644 --- a/go.sum +++ b/go.sum @@ -21,6 +21,8 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudsmith-io/cloudsmith-api-go v0.0.41 h1:7bPbyD3FIN8PmmZQg43O/y8OTkFFZ2ZxcSbrMcdrjHE= github.com/cloudsmith-io/cloudsmith-api-go v0.0.41/go.mod h1:xHTDgU8TyMXiWUZdn2OQR7AaZdz9M5SrNenyQU44zGQ= +github.com/cloudsmith-io/cloudsmith-api-go v0.0.42-0.20241129202450-bd5381591ce5 h1:vU6M9CeLmTU9xJj5G7pCQ9F8o+zl4pSfKnmGxB+miLE= +github.com/cloudsmith-io/cloudsmith-api-go v0.0.42-0.20241129202450-bd5381591ce5/go.mod h1:xHTDgU8TyMXiWUZdn2OQR7AaZdz9M5SrNenyQU44zGQ= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= From 740191b6829617270974eaee70d433ac1b759fb8 Mon Sep 17 00:00:00 2001 From: Ian Duffy Date: Fri, 29 Nov 2024 21:24:56 +0000 Subject: [PATCH 3/8] Fix tests --- cloudsmith/resource_oidc_test.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/cloudsmith/resource_oidc_test.go b/cloudsmith/resource_oidc_test.go index 492d7da..1f984b8 100644 --- a/cloudsmith/resource_oidc_test.go +++ b/cloudsmith/resource_oidc_test.go @@ -31,24 +31,26 @@ func TestAccOidc_basic(t *testing.T) { resource.TestCheckResourceAttr("cloudsmith_oidc.test", "enabled", "true"), resource.TestCheckResourceAttr("cloudsmith_oidc.test", "name", "test-oidc-terraform-provider"), resource.TestCheckResourceAttr("cloudsmith_oidc.test", "provider_url", "https://test.com"), - resource.TestCheckResourceAttr("cloudsmith_oidc.test", "service_accounts.0", "test-oidc-service-account"), + resource.TestMatchResourceAttr("cloudsmith_oidc.test", "service_accounts.0", regexp.MustCompile("^test-oidc-service-account.*$")), ), }, { Config: testAccOidcConfigBasicUpdateName, Check: resource.ComposeTestCheckFunc( + testAccServiceCheckExists("cloudsmith_service.test"), testAccOidcCheckExists("cloudsmith_oidc.test"), resource.TestCheckResourceAttr("cloudsmith_oidc.test", "namespace", os.Getenv("CLOUDSMITH_NAMESPACE")), resource.TestCheckResourceAttr("cloudsmith_oidc.test", "claims.key", "value2"), resource.TestCheckResourceAttr("cloudsmith_oidc.test", "enabled", "false"), resource.TestCheckResourceAttr("cloudsmith_oidc.test", "name", "test-oidc-terraform-provider-updated"), resource.TestCheckResourceAttr("cloudsmith_oidc.test", "provider_url", "https://test.com"), - resource.TestCheckResourceAttr("cloudsmith_oidc.test", "service_accounts.0", "test-oidc-service-account"), + resource.TestMatchResourceAttr("cloudsmith_oidc.test", "service_accounts.0", regexp.MustCompile("^test-oidc-service-account.*$")), ), }, { Config: testAccOidcConfigBasicUpdateProps, Check: resource.ComposeTestCheckFunc( + testAccServiceCheckExists("cloudsmith_service.test"), testAccOidcCheckExists("cloudsmith_oidc.test"), resource.TestCheckResourceAttr("cloudsmith_oidc.test", "namespace", os.Getenv("CLOUDSMITH_NAMESPACE")), resource.TestCheckResourceAttr("cloudsmith_oidc.test", "claims.key", "value"), @@ -56,7 +58,7 @@ func TestAccOidc_basic(t *testing.T) { resource.TestCheckResourceAttr("cloudsmith_oidc.test", "enabled", "true"), resource.TestCheckResourceAttr("cloudsmith_oidc.test", "name", "test-oidc-terraform-provider-updated"), resource.TestCheckResourceAttr("cloudsmith_oidc.test", "provider_url", "https://test-updated-url.com"), - resource.TestCheckResourceAttr("cloudsmith_oidc.test", "service_accounts.0", "test-oidc-service-account"), + resource.TestMatchResourceAttr("cloudsmith_oidc.test", "service_accounts.0", regexp.MustCompile("^test-oidc-service-account.*$")), ), }, { @@ -127,7 +129,7 @@ resource "cloudsmith_oidc" "test" { enabled = true name = "test-oidc-terraform-provider" provider_url = "https://test.com" - service_accounts = [cloudsmith_service.test.name] + service_accounts = [cloudsmith_service.test.slug] } `, os.Getenv("CLOUDSMITH_NAMESPACE"), os.Getenv("CLOUDSMITH_NAMESPACE")) @@ -146,7 +148,7 @@ resource "cloudsmith_oidc" "test" { enabled = false name = "test-oidc-terraform-provider-updated" provider_url = "https://test.com" - service_accounts = [cloudsmith_service.test.name] + service_accounts = [cloudsmith_service.test.slug] } `, os.Getenv("CLOUDSMITH_NAMESPACE"), os.Getenv("CLOUDSMITH_NAMESPACE")) @@ -166,7 +168,7 @@ resource "cloudsmith_oidc" "test" { enabled = true name = "test-oidc-terraform-provider-updated" provider_url = "https://test-updated-url.com" - service_accounts = [cloudsmith_service.test.name] + service_accounts = [cloudsmith_service.test.slug] } `, os.Getenv("CLOUDSMITH_NAMESPACE"), os.Getenv("CLOUDSMITH_NAMESPACE")) @@ -187,7 +189,7 @@ resource "cloudsmith_oidc" "test" { enabled = true name = "test-oidc-terraform-provider-updated" provider_url = "invalid-url" - service_accounts = [cloudsmith_service.test.name] + service_accounts = [cloudsmith_service.test.slug] } `, os.Getenv("CLOUDSMITH_NAMESPACE"), os.Getenv("CLOUDSMITH_NAMESPACE")) From 5535c54c98eebbc5a047a5f5959bb88a266857dc Mon Sep 17 00:00:00 2001 From: Ian Duffy Date: Thu, 28 Nov 2024 00:35:36 +0000 Subject: [PATCH 4/8] feat(ENG-6470): add support for configuring saml authorisation --- cloudsmith/provider.go | 1 + cloudsmith/resource_saml_auth.go | 254 ++++++++++++++++++++++++++ cloudsmith/resource_saml_auth_test.go | 154 ++++++++++++++++ docs/resources/saml_auth.md | 49 +++++ 4 files changed, 458 insertions(+) create mode 100644 cloudsmith/resource_saml_auth.go create mode 100644 cloudsmith/resource_saml_auth_test.go create mode 100644 docs/resources/saml_auth.md diff --git a/cloudsmith/provider.go b/cloudsmith/provider.go index 372e1ed..c7487f5 100644 --- a/cloudsmith/provider.go +++ b/cloudsmith/provider.go @@ -56,6 +56,7 @@ func Provider() *schema.Provider { "cloudsmith_oidc": resourceOIDC(), "cloudsmith_manage_team": resourceManageTeam(), "cloudsmith_saml": resourceSAML(), + "cloudsmith_saml_auth": resourceSAMLAuth(), "cloudsmith_repository_retention_rule": resourceRepoRetentionRule(), }, } diff --git a/cloudsmith/resource_saml_auth.go b/cloudsmith/resource_saml_auth.go new file mode 100644 index 0000000..35901e7 --- /dev/null +++ b/cloudsmith/resource_saml_auth.go @@ -0,0 +1,254 @@ +// Package cloudsmith provides Terraform provider functionality for managing Cloudsmith resources. +package cloudsmith + +import ( + "context" + "crypto/sha256" + "encoding/hex" + "fmt" + "net/http" + "strings" + + "github.com/cloudsmith-io/cloudsmith-api-go" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +// samlAuthCreate handles the creation of a new SAML authentication configuration +func samlAuthCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + pc := m.(*providerConfig) + organization := d.Get("organization").(string) + + samlAuth, err := buildSAMLAuthPatch(d) + if err != nil { + return diag.FromErr(fmt.Errorf("error building SAML auth request: %w", err)) + } + + req := pc.APIClient.OrgsApi.OrgsSamlAuthenticationPartialUpdate(pc.Auth, organization).Data(*samlAuth) + result, resp, err := pc.APIClient.OrgsApi.OrgsSamlAuthenticationPartialUpdateExecute(req) + if err != nil { + return diag.FromErr(handleSAMLAuthError(err, resp, "creating SAML authentication")) + } + + d.SetId(generateSAMLAuthID(organization, result)) + return samlAuthRead(ctx, d, m) +} + +// samlAuthRead retrieves the current SAML authentication configuration +func samlAuthRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + pc := m.(*providerConfig) + organization := d.Get("organization").(string) + + samlAuth, resp, err := pc.APIClient.OrgsApi.OrgsSamlAuthenticationRead(pc.Auth, organization).Execute() + if err != nil { + if resp != nil && resp.StatusCode == http.StatusNotFound { + d.SetId("") + return nil + } + return diag.FromErr(handleSAMLAuthError(err, resp, "reading SAML authentication")) + } + + if err := setSAMLAuthFields(d, organization, samlAuth); err != nil { + return diag.FromErr(err) + } + + return nil +} + +// samlAuthUpdate modifies an existing SAML authentication configuration +func samlAuthUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + pc := m.(*providerConfig) + organization := d.Get("organization").(string) + + samlAuth, err := buildSAMLAuthPatch(d) + if err != nil { + return diag.FromErr(fmt.Errorf("error building SAML auth request: %w", err)) + } + + req := pc.APIClient.OrgsApi.OrgsSamlAuthenticationPartialUpdate(pc.Auth, organization).Data(*samlAuth) + _, resp, err := pc.APIClient.OrgsApi.OrgsSamlAuthenticationPartialUpdateExecute(req) + if err != nil { + return diag.FromErr(handleSAMLAuthError(err, resp, "updating SAML authentication")) + } + + return samlAuthRead(ctx, d, m) +} + +// samlAuthDelete disables SAML authentication for the organization +func samlAuthDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + pc := m.(*providerConfig) + organization := d.Get("organization").(string) + + samlAuth := cloudsmith.NewOrganizationSAMLAuthRequestPatch() + samlAuth.SetSamlAuthEnabled(false) + samlAuth.SetSamlAuthEnforced(false) + samlAuth.SetSamlMetadataInline("") + samlAuth.SetSamlMetadataUrl("") + + req := pc.APIClient.OrgsApi.OrgsSamlAuthenticationPartialUpdate(pc.Auth, organization).Data(*samlAuth) + _, resp, err := pc.APIClient.OrgsApi.OrgsSamlAuthenticationPartialUpdateExecute(req) + if err != nil { + return diag.FromErr(handleSAMLAuthError(err, resp, "deleting SAML authentication")) + } + + d.SetId("") + return nil +} + +// samlAuthImport handles importing existing SAML authentication configurations +func samlAuthImport(ctx context.Context, d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { + pc := m.(*providerConfig) + organization := d.Id() + + samlAuth, resp, err := pc.APIClient.OrgsApi.OrgsSamlAuthenticationRead(pc.Auth, organization).Execute() + if err != nil { + if resp != nil && resp.StatusCode == http.StatusNotFound { + return nil, fmt.Errorf("SAML authentication not found for organization %s", organization) + } + return nil, handleSAMLAuthError(err, resp, "importing SAML authentication") + } + + d.Set("organization", organization) + d.SetId(generateSAMLAuthID(organization, samlAuth)) + + if err := setSAMLAuthFields(d, organization, samlAuth); err != nil { + return nil, err + } + + return []*schema.ResourceData{d}, nil +} + +// buildSAMLAuthPatch creates a new SAML authentication patch request from the resource data +func buildSAMLAuthPatch(d *schema.ResourceData) (*cloudsmith.OrganizationSAMLAuthRequestPatch, error) { + samlAuth := cloudsmith.NewOrganizationSAMLAuthRequestPatch() + + samlAuth.SetSamlAuthEnabled(d.Get("saml_auth_enabled").(bool)) + samlAuth.SetSamlAuthEnforced(d.Get("saml_auth_enforced").(bool)) + + if v, ok := d.GetOk("saml_metadata_inline"); ok { + samlAuth.SetSamlMetadataInline(v.(string)) + samlAuth.SetSamlMetadataUrl("") + } + + if v, ok := d.GetOk("saml_metadata_url"); ok { + samlAuth.SetSamlMetadataUrl(v.(string)) + samlAuth.SetSamlMetadataInline("") + } + + return samlAuth, nil +} + +// setSAMLAuthFields updates the resource data with values from the API response +func setSAMLAuthFields(d *schema.ResourceData, organization string, samlAuth *cloudsmith.OrganizationSAMLAuth) error { + // Helper function to reduce repetition and standardize error handling + setField := func(key string, value interface{}) error { + if err := d.Set(key, value); err != nil { + return fmt.Errorf("error setting %s: %w", key, err) + } + return nil + } + + // Set the basic fields first - these are always set regardless of their value + if err := setField("organization", organization); err != nil { + return err + } + if err := setField("saml_auth_enabled", samlAuth.GetSamlAuthEnabled()); err != nil { + return err + } + if err := setField("saml_auth_enforced", samlAuth.GetSamlAuthEnforced()); err != nil { + return err + } + + // Handle inline metadata - only set if non-empty + if inlineMetadata := samlAuth.GetSamlMetadataInline(); inlineMetadata != "" { + if err := setField("saml_metadata_inline", inlineMetadata); err != nil { + return err + } + } + + // Handle URL metadata with null handling + url, hasURL := samlAuth.GetSamlMetadataUrlOk() + if !hasURL || *url == "" { + return setField("saml_metadata_url", nil) + } + return setField("saml_metadata_url", url) +} + +// generateSAMLAuthID creates a unique identifier for the SAML authentication resource +func generateSAMLAuthID(organization string, samlAuth *cloudsmith.OrganizationSAMLAuth) string { + data := organization + + if samlAuth != nil { + data += fmt.Sprintf("-%t", samlAuth.GetSamlAuthEnabled()) + data += fmt.Sprintf("-%t", samlAuth.GetSamlAuthEnforced()) + + if url, hasURL := samlAuth.GetSamlMetadataUrlOk(); hasURL { + data += fmt.Sprintf("-%s", *url) + } + + // Include inline metadata if present + if metadata := samlAuth.GetSamlMetadataInline(); metadata != "" { + data += fmt.Sprintf("-%s", metadata) + } + } + + hash := sha256.Sum256([]byte(data)) + return hex.EncodeToString(hash[:]) +} + +// handleSAMLAuthError creates formatted error messages for API operations +func handleSAMLAuthError(err error, resp *http.Response, action string) error { + if resp != nil { + return fmt.Errorf("error %s: %v (status: %d)", action, err, resp.StatusCode) + } + return fmt.Errorf("error %s: %v", action, err) +} + +// resourceSAMLAuth returns a schema.Resource for managing SAML authentication configuration. +// This resource allows configuring SAML authentication settings for a Cloudsmith organization. +func resourceSAMLAuth() *schema.Resource { + return &schema.Resource{ + CreateContext: samlAuthCreate, + ReadContext: samlAuthRead, + UpdateContext: samlAuthUpdate, + DeleteContext: samlAuthDelete, + + Importer: &schema.ResourceImporter{ + StateContext: samlAuthImport, + }, + + Schema: map[string]*schema.Schema{ + "organization": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Organization slug for SAML authentication", + }, + "saml_auth_enabled": { + Type: schema.TypeBool, + Required: true, + Description: "Enable SAML authentication for the organization", + }, + "saml_auth_enforced": { + Type: schema.TypeBool, + Required: true, + Description: "Enforce SAML authentication for the organization", + }, + "saml_metadata_inline": { + Type: schema.TypeString, + Optional: true, + Description: "Inline SAML metadata XML", + ExactlyOneOf: []string{"saml_metadata_inline", "saml_metadata_url"}, + StateFunc: func(v interface{}) string { + return strings.TrimSpace(v.(string)) + }, + }, + "saml_metadata_url": { + Type: schema.TypeString, + Optional: true, + Description: "URL to fetch SAML metadata", + ExactlyOneOf: []string{"saml_metadata_inline", "saml_metadata_url"}, + }, + }, + } +} diff --git a/cloudsmith/resource_saml_auth_test.go b/cloudsmith/resource_saml_auth_test.go new file mode 100644 index 0000000..cc70938 --- /dev/null +++ b/cloudsmith/resource_saml_auth_test.go @@ -0,0 +1,154 @@ +package cloudsmith + +import ( + "fmt" + "os" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccSAMLAuth_basic(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccSAMLAuthCheckDestroy("cloudsmith_saml_auth.test"), + Steps: []resource.TestStep{ + { + // Basic configuration with URL-based metadata + Config: testAccSAMLAuthConfigBasic, + Check: resource.ComposeTestCheckFunc( + testAccSAMLAuthCheckExists("cloudsmith_saml_auth.test"), + resource.TestCheckResourceAttr("cloudsmith_saml_auth.test", "saml_auth_enabled", "true"), + resource.TestCheckResourceAttr("cloudsmith_saml_auth.test", "saml_auth_enforced", "false"), + resource.TestCheckResourceAttr("cloudsmith_saml_auth.test", "saml_metadata_url", "https://test.idp.example.com/metadata.xml"), + resource.TestCheckNoResourceAttr("cloudsmith_saml_auth.test", "saml_metadata_inline"), + ), + }, + { + // Update to use inline metadata + Config: testAccSAMLAuthConfigInlineMetadata, + Check: resource.ComposeTestCheckFunc( + testAccSAMLAuthCheckExists("cloudsmith_saml_auth.test"), + resource.TestCheckResourceAttr("cloudsmith_saml_auth.test", "saml_metadata_inline", testSAMLMetadata), + resource.TestCheckResourceAttr("cloudsmith_saml_auth.test", "saml_metadata_url", ""), + ), + }, + { + // Enable enforcement + Config: testAccSAMLAuthConfigEnforced, + Check: resource.ComposeTestCheckFunc( + testAccSAMLAuthCheckExists("cloudsmith_saml_auth.test"), + resource.TestCheckResourceAttr("cloudsmith_saml_auth.test", "saml_auth_enforced", "true"), + ), + }, + { + ResourceName: "cloudsmith_saml_auth.test", + ImportState: true, + ImportStateIdFunc: func(s *terraform.State) (string, error) { + return os.Getenv("CLOUDSMITH_NAMESPACE"), nil + }, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccSAMLAuthCheckDestroy(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + resourceState, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("resource not found: %s", resourceName) + } + + if resourceState.Primary.ID == "" { + return fmt.Errorf("resource id not set") + } + + pc := testAccProvider.Meta().(*providerConfig) + organization := resourceState.Primary.Attributes["organization"] + + req := pc.APIClient.OrgsApi.OrgsSamlAuthenticationRead(pc.Auth, organization) + samlAuth, resp, err := pc.APIClient.OrgsApi.OrgsSamlAuthenticationReadExecute(req) + if err != nil && !is404(resp) { + return fmt.Errorf("unable to verify SAML auth deletion: %w", err) + } + defer resp.Body.Close() + + // Resource is considered destroyed if SAML auth is disabled + if samlAuth != nil && samlAuth.GetSamlAuthEnabled() { + return fmt.Errorf("SAML authentication still enabled for organization: %s", organization) + } + + return nil + } +} + +func testAccSAMLAuthCheckExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + resourceState, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("resource not found: %s", resourceName) + } + + if resourceState.Primary.ID == "" { + return fmt.Errorf("resource id not set") + } + + pc := testAccProvider.Meta().(*providerConfig) + organization := resourceState.Primary.Attributes["organization"] + + req := pc.APIClient.OrgsApi.OrgsSamlAuthenticationRead(pc.Auth, organization) + _, resp, err := pc.APIClient.OrgsApi.OrgsSamlAuthenticationReadExecute(req) + if err != nil { + return fmt.Errorf("error checking SAML auth existence: %w", err) + } + defer resp.Body.Close() + + return nil + } +} + +// Sample SAML metadata for testing +var testSAMLMetadata = strings.TrimSpace(` + + + + +`) + +var testAccSAMLAuthConfigBasic = strings.TrimSpace(fmt.Sprintf(` +resource "cloudsmith_saml_auth" "test" { + organization = "%s" + saml_auth_enabled = true + saml_auth_enforced = false + saml_metadata_url = "https://test.idp.example.com/metadata.xml" +} +`, os.Getenv("CLOUDSMITH_NAMESPACE"))) + +var testAccSAMLAuthConfigInlineMetadata = strings.TrimSpace(fmt.Sprintf(` +resource "cloudsmith_saml_auth" "test" { + organization = "%s" + saml_auth_enabled = true + saml_auth_enforced = false + saml_metadata_inline = < + # + # + # + # + # + # EOF +} +``` + +## Argument Reference + +The following arguments are supported: + +* `organization` - (Required) Organization slug for SAML authentication. This value cannot be changed after creation. +* `saml_auth_enabled` - (Required) Enable or disable SAML authentication for the organization. +* `saml_auth_enforced` - (Required) Whether to enforce SAML authentication for the organization. +* `saml_metadata_url` - (Optional) URL to fetch SAML metadata from the identity provider. Exactly one of `saml_metadata_url` or `saml_metadata_inline` must be specified. +* `saml_metadata_inline` - (Optional) Inline SAML metadata XML from the identity provider. Exactly one of `saml_metadata_url` or `saml_metadata_inline` must be specified. + +## Import + +SAML authentication configuration can be imported using the organization slug: + +```shell +terraform import cloudsmith_saml_auth.example my-organization +``` From 4d672a916438a76de30b79dd3d1730238bdd867a Mon Sep 17 00:00:00 2001 From: Ian Duffy Date: Fri, 29 Nov 2024 22:05:07 +0000 Subject: [PATCH 5/8] Fix tests --- cloudsmith/resource_saml_auth.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cloudsmith/resource_saml_auth.go b/cloudsmith/resource_saml_auth.go index 35901e7..b9244aa 100644 --- a/cloudsmith/resource_saml_auth.go +++ b/cloudsmith/resource_saml_auth.go @@ -48,6 +48,9 @@ func samlAuthRead(ctx context.Context, d *schema.ResourceData, m interface{}) di return diag.FromErr(handleSAMLAuthError(err, resp, "reading SAML authentication")) } + d.Set("organization", organization) + d.SetId(generateSAMLAuthID(organization, samlAuth)) + if err := setSAMLAuthFields(d, organization, samlAuth); err != nil { return diag.FromErr(err) } From 96f49519f67ea065cfaf32c1b9993aea2c1bebc3 Mon Sep 17 00:00:00 2001 From: Ian Duffy Date: Sun, 1 Dec 2024 21:21:46 +0000 Subject: [PATCH 6/8] chore(no-ticket): valid provided credentials in the plan phase --- cloudsmith/provider_config.go | 5 +++ cloudsmith/provider_test.go | 62 ++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/cloudsmith/provider_config.go b/cloudsmith/provider_config.go index 70d2ab3..92f6860 100644 --- a/cloudsmith/provider_config.go +++ b/cloudsmith/provider_config.go @@ -46,6 +46,11 @@ func newProviderConfig(apiHost, apiKey, userAgent string) (*providerConfig, diag }, ) + req := apiClient.UserApi.UserSelf(auth) + if _, _, err := apiClient.UserApi.UserSelfExecute(req); err != nil { + return nil, diag.FromErr(errors.New("invalid API credentials")) + } + return &providerConfig{Auth: auth, APIClient: apiClient}, nil } diff --git a/cloudsmith/provider_test.go b/cloudsmith/provider_test.go index d206f86..112c2e8 100644 --- a/cloudsmith/provider_test.go +++ b/cloudsmith/provider_test.go @@ -2,9 +2,14 @@ package cloudsmith import ( + "fmt" + "net/http" + "net/http/httptest" "os" + "regexp" "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -31,8 +36,63 @@ func testAccPreCheck(t *testing.T) { if v := os.Getenv("CLOUDSMITH_API_KEY"); v == "" { t.Fatal("CLOUDSMITH_API_KEY must be set for acceptance tests") } - if v := os.Getenv("CLOUDSMITH_NAMESPACE"); v == "" { t.Fatal("CLOUDSMITH_NAMESPACE must be set for acceptance tests") } } +func TestAccProvider_UserSelfValidation(t *testing.T) { + // Create mock server + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/user/self/" { + w.Header().Set("Content-Type", "application/json") + if r.Header.Get("X-Api-Key") == "valid-token" { + w.WriteHeader(http.StatusOK) + fmt.Fprintln(w, `{"email": "test@example.com", "name": "Test User", "slug": "test-user", "slug_perm": "test-user"}`) + } else { + w.WriteHeader(http.StatusUnauthorized) + fmt.Fprintln(w, `{"error": "invalid API credentials"}`) + } + } + })) + defer server.Close() + + tests := []struct { + name string + apiKey string + }{ + { + name: "ValidToken", + apiKey: "valid-token", + }, + { + name: "InvalidToken", + apiKey: "invalid-token", + }, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Setenv("CLOUDSMITH_API_HOST", server.URL) + t.Setenv("CLOUDSMITH_API_KEY", tc.apiKey) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: selfConfig, + ExpectError: regexp.MustCompile("invalid API credentials"), + SkipFunc: func() (bool, error) { + // Skip error check for valid token case + return tc.apiKey == "valid-token", nil + }, + }, + }, + }) + }) + } +} + +var selfConfig string = ` +data "cloudsmith_user_self" "this" { +}` From ba92d2cfaf9a395e072b792678cc6cf6450e8774 Mon Sep 17 00:00:00 2001 From: Ian Duffy Date: Sun, 1 Dec 2024 22:09:14 +0000 Subject: [PATCH 7/8] Fix tests --- cloudsmith/resource_service_test.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/cloudsmith/resource_service_test.go b/cloudsmith/resource_service_test.go index fa2f7dc..40dedb0 100644 --- a/cloudsmith/resource_service_test.go +++ b/cloudsmith/resource_service_test.go @@ -4,6 +4,7 @@ package cloudsmith import ( "fmt" "os" + "regexp" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -32,7 +33,7 @@ func TestAccService_basic(t *testing.T) { testAccServiceCheckExists("cloudsmith_service.test"), // check a sample of computed properties have been set correctly resource.TestCheckResourceAttr("cloudsmith_service.test", "description", ""), - resource.TestCheckResourceAttr("cloudsmith_service.test", "slug", "tf-test-service"), + resource.TestMatchResourceAttr("cloudsmith_service.test", "slug", regexp.MustCompile("^tf-test-service.*$")), resource.TestCheckResourceAttrSet("cloudsmith_service.test", "key"), resource.TestCheckResourceAttr("cloudsmith_service.test", "role", "Member"), resource.TestCheckNoResourceAttr("cloudsmith_service.test", "team.#"), @@ -60,13 +61,15 @@ func TestAccService_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccServiceCheckExists("cloudsmith_service.test"), resource.TestCheckResourceAttrSet("cloudsmith_service.test", "team.#"), - resource.TestCheckTypeSetElemNestedAttrs("cloudsmith_service.test", "team.*", map[string]string{ - "slug": "tf-test-team-svc", - "role": "Member", + + resource.TestMatchTypeSetElemNestedAttrs("cloudsmith_service.test", "team.*", map[string]*regexp.Regexp{ + "slug": regexp.MustCompile("^tf-test-team-svc(-[^2].*)?$"), + "role": regexp.MustCompile("^Member$"), }), - resource.TestCheckTypeSetElemNestedAttrs("cloudsmith_service.test", "team.*", map[string]string{ - "slug": "tf-test-team-svc-2", - "role": "Manager", + + resource.TestMatchTypeSetElemNestedAttrs("cloudsmith_service.test", "team.*", map[string]*regexp.Regexp{ + "slug": regexp.MustCompile("^tf-test-team-svc-2.*$"), + "role": regexp.MustCompile("^Manager$"), }), ), }, From ce599e0d2caf4ed9ddd1a2990f5fd9888cb9fbdd Mon Sep 17 00:00:00 2001 From: Ian Duffy Date: Tue, 3 Dec 2024 11:10:32 +0000 Subject: [PATCH 8/8] Update resource_saml_auth_test.go --- cloudsmith/resource_saml_auth_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/cloudsmith/resource_saml_auth_test.go b/cloudsmith/resource_saml_auth_test.go index cc70938..2bfca75 100644 --- a/cloudsmith/resource_saml_auth_test.go +++ b/cloudsmith/resource_saml_auth_test.go @@ -11,8 +11,6 @@ import ( ) func TestAccSAMLAuth_basic(t *testing.T) { - t.Parallel() - resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders,