From 7ce6feb724280dd5787a6a1b30539981d3f33cb0 Mon Sep 17 00:00:00 2001 From: Max Coulombe <109547106+maxcoulombe@users.noreply.github.com> Date: Fri, 13 Dec 2024 13:52:31 -0500 Subject: [PATCH] HCP Vault Secrets Generic Integration (#1151) * aggregate all the provider-specific integration resource into a provider-agnostic resource --- .changelog/1151.txt | 13 + docs/resources/vault_secrets_integration.md | 224 ++++++ .../vault_secrets_integration_aws.md | 2 + .../vault_secrets_integration_confluent.md | 2 + .../vault_secrets_integration_gcp.md | 2 + .../vault_secrets_integration_mongodbatlas.md | 2 + .../vault_secrets_integration_twilio.md | 2 + .../hcp_vault_secrets_integration/import.sh | 4 + .../hcp_vault_secrets_integration/resource.tf | 83 ++ go.mod | 2 +- go.sum | 4 +- internal/provider/provider.go | 10 +- .../resource_vault_secrets_integration.go | 723 ++++++++++++++++++ ...ult_secrets_integration_aws_deprecated.go} | 0 ...urce_vault_secrets_integration_aws_test.go | 127 +-- ...t_secrets_integration_azure_deprecated.go} | 0 ...ce_vault_secrets_integration_azure_test.go | 55 +- ...crets_integration_confluent_deprecated.go} | 3 +- ...ault_secrets_integration_confluent_test.go | 27 +- ...ult_secrets_integration_gcp_deprecated.go} | 0 ...urce_vault_secrets_integration_gcp_test.go | 53 +- ...ts_integration_mongodbatlas_deprecated.go} | 0 ...t_secrets_integration_mongodbatlas_test.go | 27 +- ..._secrets_integration_twilio_deprecated.go} | 3 +- ...e_vault_secrets_integration_twilio_test.go | 29 +- .../resource_vault_secrets_rotating_secret.go | 4 +- .../vaultsecrets/vault_secrets_utils.go | 18 +- .../vault_secrets_integration.md.tmpl | 22 + .../vault_secrets_integration_aws.md.tmpl | 2 + ...ault_secrets_integration_confluent.md.tmpl | 2 + .../vault_secrets_integration_gcp.md.tmpl | 2 + ...t_secrets_integration_mongodbatlas.md.tmpl | 2 + .../vault_secrets_integration_twilio.md.tmpl | 2 + 33 files changed, 1294 insertions(+), 157 deletions(-) create mode 100644 .changelog/1151.txt create mode 100644 docs/resources/vault_secrets_integration.md create mode 100644 examples/resources/hcp_vault_secrets_integration/import.sh create mode 100644 examples/resources/hcp_vault_secrets_integration/resource.tf create mode 100644 internal/provider/vaultsecrets/resource_vault_secrets_integration.go rename internal/provider/vaultsecrets/{resource_vault_secrets_integration_aws.go => resource_vault_secrets_integration_aws_deprecated.go} (100%) rename internal/provider/vaultsecrets/{resource_vault_secrets_integration_azure.go => resource_vault_secrets_integration_azure_deprecated.go} (100%) rename internal/provider/vaultsecrets/{resource_vault_secrets_integration_confluent.go => resource_vault_secrets_integration_confluent_deprecated.go} (99%) rename internal/provider/vaultsecrets/{resource_vault_secrets_integration_gcp.go => resource_vault_secrets_integration_gcp_deprecated.go} (100%) rename internal/provider/vaultsecrets/{resource_vault_secrets_integration_mongodbatlas.go => resource_vault_secrets_integration_mongodbatlas_deprecated.go} (100%) rename internal/provider/vaultsecrets/{resource_vault_secrets_integration_twilio.go => resource_vault_secrets_integration_twilio_deprecated.go} (99%) create mode 100644 templates/resources/vault_secrets_integration.md.tmpl diff --git a/.changelog/1151.txt b/.changelog/1151.txt new file mode 100644 index 000000000..b2bbfd7d0 --- /dev/null +++ b/.changelog/1151.txt @@ -0,0 +1,13 @@ +```release-note:deprecation +the following resources are deprecated: + - `hcp_vault_secrets_integration_aws` + - `hcp_vault_secrets_integration_azure` + - `hcp_vault_secrets_integration_confluent` + - `hcp_vault_secrets_integration_gcp` + - `hcp_vault_secrets_integration_mongodbatlas` + - 'hcp_vault_secrets_integration_twilio' +``` + +```release-note:feature +add 'hcp_vault_secrets_integration' resource as a replacement for the provider-specific resources +``` \ No newline at end of file diff --git a/docs/resources/vault_secrets_integration.md b/docs/resources/vault_secrets_integration.md new file mode 100644 index 000000000..b6b423194 --- /dev/null +++ b/docs/resources/vault_secrets_integration.md @@ -0,0 +1,224 @@ +--- +page_title: "Resource hcp_vault_secrets_integration" +subcategory: "HCP Vault Secrets" +description: |- + The Vault Secrets integration resource manages an integration. +--- + +# hcp_vault_secrets_integration (Resource) + +The Vault Secrets integration resource manages an integration. + +## Example Usage + +```terraform +// AWS +resource "hcp_vault_secrets_integration" "example_aws_federated_identity" { + name = "my-aws-1" + capabilities = ["DYNAMIC", "ROTATION"] + provider_type = "aws" + aws_federated_workload_identity = { + audience = ">" + role_arn = "" + } +} + +resource "hcp_vault_secrets_integration" "example_aws_access_keys" { + name = "my-aws-2" + capabilities = ["DYNAMIC", "ROTATION"] + provider_type = "aws" + aws_access_keys = { + access_key_id = "" + secret_access_key = "" + } +} + +// Confluent +resource "hcp_vault_secrets_integration" "example_confluent" { + name = "my-confluent-1" + capabilities = ["ROTATION"] + provider_type = "confluent" + confluent_static_credentials = { + cloud_api_key_id = "" + cloud_api_secret = "" + } +} + +// GCP +resource "hcp_vault_secrets_integration" "example_gcp_json_service_account_key" { + name = "my-gcp-1" + capabilities = ["DYNAMIC", "ROTATION"] + provider_type = "gcp" + gcp_service_account_key = { + credentials = file("${path.module}/my-service-account-key.json") + } +} + +resource "hcp_vault_secrets_integration" "example_gcp_base64_service_account_key" { + name = "my-gcp-2" + capabilities = ["DYNAMIC", "ROTATION"] + provider_type = "gcp" + gcp_service_account_key = { + credentials = filebase64("${path.module}/my-service-account-key.json") + } +} + +resource "hcp_vault_secrets_integration" "example_gcp_federated_identity" { + name = "my-gcp-3" + capabilities = ["DYNAMIC", "ROTATION"] + provider_type = "gcp" + gcp_federated_workload_identity = { + service_account_email = "" + audience = "" + } +} + +// MongoDB-Atlas +resource "hcp_vault_secrets_integration" "example_mongodb_atlas" { + name = "my-mongodb-1" + capabilities = ["ROTATION"] + provider_type = "mongodb-atlas" + mongodb_atlas_static_credentials = { + api_public_key = "" + api_private_key = "" + } +} + +// Twilio +resource "hcp_vault_secrets_integration" "example_twilio" { + name = "my-twilio-1" + capabilities = ["ROTATION"] + provider_type = "twilio" + twilio_static_credentials = { + account_sid = "" + api_key_secret = "" + api_key_sid = "" + } +} +``` + + +## Schema + +### Required + +- `capabilities` (Set of String) Capabilities enabled for the integration. See the Vault Secrets documentation for the list of supported capabilities per provider. +- `name` (String) The Vault Secrets integration name. +- `provider_type` (String) The provider or 3rd party platform the integration is for. + +### Optional + +- `aws_access_keys` (Attributes) AWS IAM key pair used to authenticate against the target AWS account. Cannot be used with `federated_workload_identity`. (see [below for nested schema](#nestedatt--aws_access_keys)) +- `aws_federated_workload_identity` (Attributes) (Recommended) Federated identity configuration to authenticate against the target AWS account. Cannot be used with `access_keys`. (see [below for nested schema](#nestedatt--aws_federated_workload_identity)) +- `azure_client_secret` (Attributes) Azure client secret used to authenticate against the target Azure application. Cannot be used with `federated_workload_identity`. (see [below for nested schema](#nestedatt--azure_client_secret)) +- `azure_federated_workload_identity` (Attributes) (Recommended) Federated identity configuration to authenticate against the target Azure application. Cannot be used with `client_secret`. (see [below for nested schema](#nestedatt--azure_federated_workload_identity)) +- `confluent_static_credentials` (Attributes) Confluent API key used to authenticate for cloud apis. (see [below for nested schema](#nestedatt--confluent_static_credentials)) +- `gcp_federated_workload_identity` (Attributes) (Recommended) Federated identity configuration to authenticate against the target GCP project. Cannot be used with `service_account_key`. (see [below for nested schema](#nestedatt--gcp_federated_workload_identity)) +- `gcp_service_account_key` (Attributes) GCP service account key used to authenticate against the target GCP project. Cannot be used with `federated_workload_identity`. (see [below for nested schema](#nestedatt--gcp_service_account_key)) +- `mongodb_atlas_static_credentials` (Attributes) MongoDB Atlas API key used to authenticate against the target project. (see [below for nested schema](#nestedatt--mongodb_atlas_static_credentials)) +- `project_id` (String) HCP project ID that owns the HCP Vault Secrets integration. Inferred from the provider configuration if omitted. +- `twilio_static_credentials` (Attributes) Twilio API key parts used to authenticate against the target Twilio account. (see [below for nested schema](#nestedatt--twilio_static_credentials)) + +### Read-Only + +- `organization_id` (String) HCP organization ID that owns the HCP Vault Secrets integration. +- `resource_id` (String) Resource ID used to uniquely identify the integration instance on the HCP platform. +- `resource_name` (String) Resource name used to uniquely identify the integration instance on the HCP platform. + + +### Nested Schema for `aws_access_keys` + +Required: + +- `access_key_id` (String) Key ID used with the secret key to authenticate against the target AWS account. +- `secret_access_key` (String, Sensitive) Secret key used with the key ID to authenticate against the target AWS account. + + + +### Nested Schema for `aws_federated_workload_identity` + +Required: + +- `audience` (String) Audience configured on the AWS IAM identity provider to federate access with HCP. +- `role_arn` (String) AWS IAM role ARN the integration will assume to carry operations for the appropriate capabilities. + + + +### Nested Schema for `azure_client_secret` + +Required: + +- `client_id` (String) Azure client ID corresponding to the Azure application. +- `client_secret` (String) Secret value corresponding to the Azure client secret. +- `tenant_id` (String) Azure tenant ID corresponding to the Azure application. + + + +### Nested Schema for `azure_federated_workload_identity` + +Required: + +- `audience` (String) Audience configured on the Azure federated identity credentials to federate access with HCP. +- `client_id` (String) Azure client ID corresponding to the Azure application. +- `tenant_id` (String) Azure tenant ID corresponding to the Azure application. + + + +### Nested Schema for `confluent_static_credentials` + +Required: + +- `cloud_api_key_id` (String) Public key used alongside the private key to authenticate for cloud apis. +- `cloud_api_secret` (String, Sensitive) Private key used alongside the public key to authenticate for cloud apis. + + + +### Nested Schema for `gcp_federated_workload_identity` + +Required: + +- `audience` (String) Audience configured on the GCP identity provider to federate access with HCP. +- `service_account_email` (String) GCP service account email that HVS will impersonate to carry operations for the appropriate capabilities. + + + +### Nested Schema for `gcp_service_account_key` + +Required: + +- `credentials` (String) JSON or base64 encoded service account key received from GCP. + +Read-Only: + +- `client_email` (String) Service account email corresponding to the service account key. +- `project_id` (String) GCP project ID corresponding to the service account key. + + + +### Nested Schema for `mongodb_atlas_static_credentials` + +Required: + +- `api_private_key` (String, Sensitive) Private key used alongside the public key to authenticate against the target project. +- `api_public_key` (String) Public key used alongside the private key to authenticate against the target project. + + + +### Nested Schema for `twilio_static_credentials` + +Required: + +- `account_sid` (String) Account SID for the target Twilio account. +- `api_key_secret` (String, Sensitive) Api key secret used with the api key SID to authenticate against the target Twilio account. +- `api_key_sid` (String) Api key SID to authenticate against the target Twilio account. + +## Import + +Import is supported using the following syntax: + +```shell +# Vault Secrets Integration can be imported by specifying the name of the integration +# Note that since sensitive information are never returned on the Vault Secrets API, +# the next plan or apply will show a diff for sensitive fields. +terraform import hcp_vault_secrets_integration.example my-integration-name +``` diff --git a/docs/resources/vault_secrets_integration_aws.md b/docs/resources/vault_secrets_integration_aws.md index f44aa1b6e..18d8d9e40 100644 --- a/docs/resources/vault_secrets_integration_aws.md +++ b/docs/resources/vault_secrets_integration_aws.md @@ -9,6 +9,8 @@ description: |- The Vault Secrets AWS integration resource manages an AWS integration. +~> **Note:** This resource is deprecated, please use `hcp_vault_secrets_integration` instead. + ## Example Usage ```terraform diff --git a/docs/resources/vault_secrets_integration_confluent.md b/docs/resources/vault_secrets_integration_confluent.md index 296df705b..8922758c3 100644 --- a/docs/resources/vault_secrets_integration_confluent.md +++ b/docs/resources/vault_secrets_integration_confluent.md @@ -9,6 +9,8 @@ description: |- The Vault Secrets Confluent integration resource manages an Confluent integration. +~> **Note:** This resource is deprecated, please use `hcp_vault_secrets_integration` instead. + ## Example Usage ```terraform diff --git a/docs/resources/vault_secrets_integration_gcp.md b/docs/resources/vault_secrets_integration_gcp.md index ebcb90311..305e1f7c7 100644 --- a/docs/resources/vault_secrets_integration_gcp.md +++ b/docs/resources/vault_secrets_integration_gcp.md @@ -9,6 +9,8 @@ description: |- The Vault Secrets GCP integration resource manages an GCP integration. +~> **Note:** This resource is deprecated, please use `hcp_vault_secrets_integration` instead. + ## Example Usage ```terraform diff --git a/docs/resources/vault_secrets_integration_mongodbatlas.md b/docs/resources/vault_secrets_integration_mongodbatlas.md index 6cd61dd21..1b00bdc79 100644 --- a/docs/resources/vault_secrets_integration_mongodbatlas.md +++ b/docs/resources/vault_secrets_integration_mongodbatlas.md @@ -9,6 +9,8 @@ description: |- The Vault Secrets MongoDB Atlas integration resource manages an MongoDB Atlas integration. +~> **Note:** This resource is deprecated, please use `hcp_vault_secrets_integration` instead. + ## Example Usage ```terraform diff --git a/docs/resources/vault_secrets_integration_twilio.md b/docs/resources/vault_secrets_integration_twilio.md index 7e2353c65..f8c5969ff 100644 --- a/docs/resources/vault_secrets_integration_twilio.md +++ b/docs/resources/vault_secrets_integration_twilio.md @@ -9,6 +9,8 @@ description: |- The Vault Secrets Twilio integration resource manages a Twilio integration. +~> **Note:** This resource is deprecated, please use `hcp_vault_secrets_integration` instead. + ## Example Usage ```terraform diff --git a/examples/resources/hcp_vault_secrets_integration/import.sh b/examples/resources/hcp_vault_secrets_integration/import.sh new file mode 100644 index 000000000..6140b3cc3 --- /dev/null +++ b/examples/resources/hcp_vault_secrets_integration/import.sh @@ -0,0 +1,4 @@ +# Vault Secrets Integration can be imported by specifying the name of the integration +# Note that since sensitive information are never returned on the Vault Secrets API, +# the next plan or apply will show a diff for sensitive fields. +terraform import hcp_vault_secrets_integration.example my-integration-name diff --git a/examples/resources/hcp_vault_secrets_integration/resource.tf b/examples/resources/hcp_vault_secrets_integration/resource.tf new file mode 100644 index 000000000..e1ededce0 --- /dev/null +++ b/examples/resources/hcp_vault_secrets_integration/resource.tf @@ -0,0 +1,83 @@ +// AWS +resource "hcp_vault_secrets_integration" "example_aws_federated_identity" { + name = "my-aws-1" + capabilities = ["DYNAMIC", "ROTATION"] + provider_type = "aws" + aws_federated_workload_identity = { + audience = ">" + role_arn = "" + } +} + +resource "hcp_vault_secrets_integration" "example_aws_access_keys" { + name = "my-aws-2" + capabilities = ["DYNAMIC", "ROTATION"] + provider_type = "aws" + aws_access_keys = { + access_key_id = "" + secret_access_key = "" + } +} + +// Confluent +resource "hcp_vault_secrets_integration" "example_confluent" { + name = "my-confluent-1" + capabilities = ["ROTATION"] + provider_type = "confluent" + confluent_static_credentials = { + cloud_api_key_id = "" + cloud_api_secret = "" + } +} + +// GCP +resource "hcp_vault_secrets_integration" "example_gcp_json_service_account_key" { + name = "my-gcp-1" + capabilities = ["DYNAMIC", "ROTATION"] + provider_type = "gcp" + gcp_service_account_key = { + credentials = file("${path.module}/my-service-account-key.json") + } +} + +resource "hcp_vault_secrets_integration" "example_gcp_base64_service_account_key" { + name = "my-gcp-2" + capabilities = ["DYNAMIC", "ROTATION"] + provider_type = "gcp" + gcp_service_account_key = { + credentials = filebase64("${path.module}/my-service-account-key.json") + } +} + +resource "hcp_vault_secrets_integration" "example_gcp_federated_identity" { + name = "my-gcp-3" + capabilities = ["DYNAMIC", "ROTATION"] + provider_type = "gcp" + gcp_federated_workload_identity = { + service_account_email = "" + audience = "" + } +} + +// MongoDB-Atlas +resource "hcp_vault_secrets_integration" "example_mongodb_atlas" { + name = "my-mongodb-1" + capabilities = ["ROTATION"] + provider_type = "mongodb-atlas" + mongodb_atlas_static_credentials = { + api_public_key = "" + api_private_key = "" + } +} + +// Twilio +resource "hcp_vault_secrets_integration" "example_twilio" { + name = "my-twilio-1" + capabilities = ["ROTATION"] + provider_type = "twilio" + twilio_static_credentials = { + account_sid = "" + api_key_secret = "" + api_key_sid = "" + } +} \ No newline at end of file diff --git a/go.mod b/go.mod index 1f287ace3..c65c51fe1 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/hashicorp/go-cty v1.4.1-0.20200723130312-85980079f637 github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/go-version v1.7.0 - github.com/hashicorp/hcp-sdk-go v0.124.0 + github.com/hashicorp/hcp-sdk-go v0.126.0 github.com/hashicorp/terraform-plugin-docs v0.19.4 github.com/hashicorp/terraform-plugin-framework v1.5.0 github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 diff --git a/go.sum b/go.sum index 3d88edefb..f70ccc192 100644 --- a/go.sum +++ b/go.sum @@ -124,8 +124,8 @@ github.com/hashicorp/hc-install v0.7.0 h1:Uu9edVqjKQxxuD28mR5TikkKDd/p55S8vzPC16 github.com/hashicorp/hc-install v0.7.0/go.mod h1:ELmmzZlGnEcqoUMKUuykHaPCIR1sYLYX+KSggWSKZuA= github.com/hashicorp/hcl/v2 v2.19.1 h1://i05Jqznmb2EXqa39Nsvyan2o5XyMowW5fnCKW5RPI= github.com/hashicorp/hcl/v2 v2.19.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= -github.com/hashicorp/hcp-sdk-go v0.124.0 h1:Th4qCAAqlPrC5s2riHnMTsHFIZ5GsFWzK7l2W7vqsN4= -github.com/hashicorp/hcp-sdk-go v0.124.0/go.mod h1:vQ4fzdL1AmhIAbCw+4zmFe5Hbpajj3NvRWkJoVuxmAk= +github.com/hashicorp/hcp-sdk-go v0.126.0 h1:/ByCyXaKrwJwK5SMjp/JFK3ZbVqDxEaADQev3t6odI4= +github.com/hashicorp/hcp-sdk-go v0.126.0/go.mod h1:vQ4fzdL1AmhIAbCw+4zmFe5Hbpajj3NvRWkJoVuxmAk= 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.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 288536ef7..735195a50 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -154,14 +154,16 @@ func (p *ProviderFramework) Resources(ctx context.Context) []func() resource.Res vaultsecrets.NewVaultSecretsSecretResource, vaultsecrets.NewVaultSecretsAppIAMPolicyResource, vaultsecrets.NewVaultSecretsAppIAMBindingResource, + vaultsecrets.NewVaultSecretsIntegrationResource, + vaultsecrets.NewVaultSecretsDynamicSecretResource, + vaultsecrets.NewVaultSecretsRotatingSecretResource, + // Vault Secrets Deprecated vaultsecrets.NewVaultSecretsIntegrationAWSResource, + vaultsecrets.NewVaultSecretsIntegrationAzureResource, + vaultsecrets.NewVaultSecretsIntegrationsConfluentResource, vaultsecrets.NewVaultSecretsIntegrationGCPResource, vaultsecrets.NewVaultSecretsIntegrationMongoDBAtlasResource, vaultsecrets.NewVaultSecretsIntegrationTwilioResource, - vaultsecrets.NewVaultSecretsIntegrationsConfluentResource, - vaultsecrets.NewVaultSecretsIntegrationAzureResource, - vaultsecrets.NewVaultSecretsDynamicSecretResource, - vaultsecrets.NewVaultSecretsRotatingSecretResource, // IAM iam.NewServicePrincipalResource, iam.NewServicePrincipalKeyResource, diff --git a/internal/provider/vaultsecrets/resource_vault_secrets_integration.go b/internal/provider/vaultsecrets/resource_vault_secrets_integration.go new file mode 100644 index 000000000..16d6f5c0b --- /dev/null +++ b/internal/provider/vaultsecrets/resource_vault_secrets_integration.go @@ -0,0 +1,723 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package vaultsecrets + +import ( + "context" + "fmt" + + "github.com/hashicorp/hcp-sdk-go/clients/cloud-vault-secrets/stable/2023-11-28/client/secret_service" + secretmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-vault-secrets/stable/2023-11-28/models" + "github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "golang.org/x/exp/maps" + + "github.com/hashicorp/terraform-provider-hcp/internal/clients" + "github.com/hashicorp/terraform-provider-hcp/internal/provider/modifiers" +) + +var exactlyOneIntegrationTypeFieldsValidator = objectvalidator.ExactlyOneOf( + path.Expressions{ + path.MatchRoot("aws_access_keys"), + path.MatchRoot("aws_federated_workload_identity"), + path.MatchRoot("azure_client_secret"), + path.MatchRoot("azure_federated_workload_identity"), + path.MatchRoot("confluent_static_credentials"), + path.MatchRoot("gcp_service_account_key"), + path.MatchRoot("gcp_federated_workload_identity"), + path.MatchRoot("mongodb_atlas_static_credentials"), + path.MatchRoot("twilio_static_credentials"), + }..., +) + +type Integration struct { + // Input fields + ProjectID types.String `tfsdk:"project_id"` + Name types.String `tfsdk:"name"` + Capabilities types.Set `tfsdk:"capabilities"` + Provider types.String `tfsdk:"provider_type"` + + // Provider specific mutually exclusive fields + AwsAccessKeys types.Object `tfsdk:"aws_access_keys"` + AwsFederatedWorkloadIdentity types.Object `tfsdk:"aws_federated_workload_identity"` + AzureClientSecret types.Object `tfsdk:"azure_client_secret"` + AzureFederatedWorkloadIdentity types.Object `tfsdk:"azure_federated_workload_identity"` + ConfluentStaticCredentialDetails types.Object `tfsdk:"confluent_static_credentials"` + GcpServiceAccountKey types.Object `tfsdk:"gcp_service_account_key"` + GcpFederatedWorkloadIdentity types.Object `tfsdk:"gcp_federated_workload_identity"` + MongoDBAtlasStaticCredentials types.Object `tfsdk:"mongodb_atlas_static_credentials"` + TwilioStaticCredentials types.Object `tfsdk:"twilio_static_credentials"` + + // Computed fields + OrganizationID types.String `tfsdk:"organization_id"` + ResourceID types.String `tfsdk:"resource_id"` + ResourceName types.String `tfsdk:"resource_name"` + + // Inner API-compatible models derived from the Terraform fields + capabilities []*secretmodels.Secrets20231128Capability `tfsdk:"-"` + awsAccessKeys *secretmodels.Secrets20231128AwsAccessKeysRequest `tfsdk:"-"` + awsFederatedWorkloadIdentity *secretmodels.Secrets20231128AwsFederatedWorkloadIdentityRequest `tfsdk:"-"` + azureClientSecret *secretmodels.Secrets20231128AzureClientSecretRequest `tfsdk:"-"` + azureFederatedWorkloadIdentity *secretmodels.Secrets20231128AzureFederatedWorkloadIdentityRequest `tfsdk:"-"` + confluentStaticCredentials *secretmodels.Secrets20231128ConfluentStaticCredentialsRequest `tfsdk:"-"` + gcpServiceAccountKey *secretmodels.Secrets20231128GcpServiceAccountKeyRequest `tfsdk:"-"` + gcpFederatedWorkloadIdentity *secretmodels.Secrets20231128GcpFederatedWorkloadIdentityRequest `tfsdk:"-"` + mongoDBAtlasStaticCredentials *secretmodels.Secrets20231128MongoDBAtlasStaticCredentialsRequest `tfsdk:"-"` + twilioStaticCredentials *secretmodels.Secrets20231128TwilioStaticCredentialsRequest `tfsdk:"-"` +} + +var _ resource.Resource = &resourceVaultSecretsIntegration{} +var _ resource.ResourceWithConfigure = &resourceVaultSecretsIntegration{} +var _ resource.ResourceWithModifyPlan = &resourceVaultSecretsIntegration{} +var _ resource.ResourceWithImportState = &resourceVaultSecretsIntegration{} + +func NewVaultSecretsIntegrationResource() resource.Resource { + return &resourceVaultSecretsIntegration{} +} + +type resourceVaultSecretsIntegration struct { + client *clients.Client +} + +func (r *resourceVaultSecretsIntegration) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_vault_secrets_integration" +} + +func (r *resourceVaultSecretsIntegration) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + attributes := map[string]schema.Attribute{ + "provider_type": schema.StringAttribute{ + Description: "The provider or 3rd party platform the integration is for.", + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Validators: []validator.String{ + stringvalidator.OneOf(ProviderStrings()...), + }, + }, + "aws_access_keys": schema.SingleNestedAttribute{ + Description: "AWS IAM key pair used to authenticate against the target AWS account. Cannot be used with `federated_workload_identity`.", + Optional: true, + Attributes: map[string]schema.Attribute{ + "access_key_id": schema.StringAttribute{ + Description: "Key ID used with the secret key to authenticate against the target AWS account.", + Required: true, + }, + "secret_access_key": schema.StringAttribute{ + Description: "Secret key used with the key ID to authenticate against the target AWS account.", + Required: true, + Sensitive: true, + }, + }, + Validators: []validator.Object{ + exactlyOneIntegrationTypeFieldsValidator, + }, + }, + "aws_federated_workload_identity": schema.SingleNestedAttribute{ + Description: "(Recommended) Federated identity configuration to authenticate against the target AWS account. Cannot be used with `access_keys`.", + Optional: true, + Attributes: map[string]schema.Attribute{ + "role_arn": schema.StringAttribute{ + Description: "AWS IAM role ARN the integration will assume to carry operations for the appropriate capabilities.", + Required: true, + }, + "audience": schema.StringAttribute{ + Description: "Audience configured on the AWS IAM identity provider to federate access with HCP.", + Required: true, + }, + }, + Validators: []validator.Object{ + exactlyOneIntegrationTypeFieldsValidator, + }, + }, + "azure_client_secret": schema.SingleNestedAttribute{ + Description: "Azure client secret used to authenticate against the target Azure application. Cannot be used with `federated_workload_identity`.", + Optional: true, + Attributes: map[string]schema.Attribute{ + "tenant_id": schema.StringAttribute{ + Description: "Azure tenant ID corresponding to the Azure application.", + Required: true, + }, + "client_id": schema.StringAttribute{ + Description: "Azure client ID corresponding to the Azure application.", + Required: true, + }, + "client_secret": schema.StringAttribute{ + Description: "Secret value corresponding to the Azure client secret.", + Required: true, + }, + }, + Validators: []validator.Object{ + exactlyOneIntegrationTypeFieldsValidator, + }, + }, + "azure_federated_workload_identity": schema.SingleNestedAttribute{ + Description: "(Recommended) Federated identity configuration to authenticate against the target Azure application. Cannot be used with `client_secret`.", + Optional: true, + Attributes: map[string]schema.Attribute{ + "tenant_id": schema.StringAttribute{ + Description: "Azure tenant ID corresponding to the Azure application.", + Required: true, + }, + "client_id": schema.StringAttribute{ + Description: "Azure client ID corresponding to the Azure application.", + Required: true, + }, + "audience": schema.StringAttribute{ + Description: "Audience configured on the Azure federated identity credentials to federate access with HCP.", + Required: true, + }, + }, + Validators: []validator.Object{ + exactlyOneIntegrationTypeFieldsValidator, + }, + }, + "confluent_static_credentials": schema.SingleNestedAttribute{ + Description: "Confluent API key used to authenticate for cloud apis.", + Optional: true, + Attributes: map[string]schema.Attribute{ + "cloud_api_key_id": schema.StringAttribute{ + Description: "Public key used alongside the private key to authenticate for cloud apis.", + Required: true, + }, + "cloud_api_secret": schema.StringAttribute{ + Description: "Private key used alongside the public key to authenticate for cloud apis.", + Required: true, + Sensitive: true, + }, + }, + Validators: []validator.Object{ + exactlyOneIntegrationTypeFieldsValidator, + }, + }, + "gcp_service_account_key": schema.SingleNestedAttribute{ + Description: "GCP service account key used to authenticate against the target GCP project. Cannot be used with `federated_workload_identity`.", + Optional: true, + Attributes: map[string]schema.Attribute{ + "credentials": schema.StringAttribute{ + Description: "JSON or base64 encoded service account key received from GCP.", + Required: true, + }, + "project_id": schema.StringAttribute{ + Description: "GCP project ID corresponding to the service account key.", + Computed: true, + }, + "client_email": schema.StringAttribute{ + Description: "Service account email corresponding to the service account key.", + Computed: true, + }, + }, + Validators: []validator.Object{ + exactlyOneIntegrationTypeFieldsValidator, + }, + }, + "gcp_federated_workload_identity": schema.SingleNestedAttribute{ + Description: "(Recommended) Federated identity configuration to authenticate against the target GCP project. Cannot be used with `service_account_key`.", + Optional: true, + Attributes: map[string]schema.Attribute{ + "service_account_email": schema.StringAttribute{ + Description: "GCP service account email that HVS will impersonate to carry operations for the appropriate capabilities.", + Required: true, + }, + "audience": schema.StringAttribute{ + Description: "Audience configured on the GCP identity provider to federate access with HCP.", + Required: true, + }, + }, + Validators: []validator.Object{ + exactlyOneIntegrationTypeFieldsValidator, + }, + }, + "mongodb_atlas_static_credentials": schema.SingleNestedAttribute{ + Description: "MongoDB Atlas API key used to authenticate against the target project.", + Optional: true, + Attributes: map[string]schema.Attribute{ + "api_public_key": schema.StringAttribute{ + Description: "Public key used alongside the private key to authenticate against the target project.", + Required: true, + }, + "api_private_key": schema.StringAttribute{ + Description: "Private key used alongside the public key to authenticate against the target project.", + Required: true, + Sensitive: true, + }, + }, + Validators: []validator.Object{ + exactlyOneIntegrationTypeFieldsValidator, + }, + }, + "twilio_static_credentials": schema.SingleNestedAttribute{ + Description: "Twilio API key parts used to authenticate against the target Twilio account.", + Optional: true, + Attributes: map[string]schema.Attribute{ + "account_sid": schema.StringAttribute{ + Description: "Account SID for the target Twilio account.", + Required: true, + }, + "api_key_sid": schema.StringAttribute{ + Description: "Api key SID to authenticate against the target Twilio account.", + Required: true, + }, + "api_key_secret": schema.StringAttribute{ + Description: "Api key secret used with the api key SID to authenticate against the target Twilio account.", + Required: true, + Sensitive: true, + }, + }, + Validators: []validator.Object{ + exactlyOneIntegrationTypeFieldsValidator, + }, + }, + } + + maps.Copy(attributes, locationAttributes) + maps.Copy(attributes, sharedIntegrationAttributes) + + resp.Schema = schema.Schema{ + MarkdownDescription: "The Vault Secrets integration resource manages an integration.", + Attributes: attributes, + } +} + +func (r *resourceVaultSecretsIntegration) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + client, ok := req.ProviderData.(*clients.Client) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected *clients.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + r.client = client +} + +func (r *resourceVaultSecretsIntegration) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { + modifiers.ModifyPlanForDefaultProjectChange(ctx, r.client.Config.ProjectID, req.State, req.Config, req.Plan, resp) +} + +func (r *resourceVaultSecretsIntegration) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + resp.Diagnostics.Append(decorateOperation[*Integration](ctx, r.client, &resp.State, req.State.Get, "reading", func(i hvsResource) (any, error) { + integration, ok := i.(*Integration) + if !ok { + return nil, fmt.Errorf("invalid integration type, expected *Integration, got: %T, this is a bug on the provider", i) + } + + response, err := r.client.VaultSecrets.GetIntegration( + secret_service.NewGetIntegrationParamsWithContext(ctx). + WithOrganizationID(integration.OrganizationID.ValueString()). + WithProjectID(integration.ProjectID.ValueString()). + WithName(integration.Name.ValueString()), nil) + if err != nil && !clients.IsResponseCodeNotFound(err) { + return nil, err + } + if response == nil || response.Payload == nil { + return nil, nil + } + return response.Payload.Integration, nil + })...) +} + +func (r *resourceVaultSecretsIntegration) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + resp.Diagnostics.Append(decorateOperation[*Integration](ctx, r.client, &resp.State, req.Plan.Get, "creating", func(i hvsResource) (any, error) { + integration, ok := i.(*Integration) + if !ok { + return nil, fmt.Errorf("invalid integration type, expected *Integration, got: %T, this is a bug on the provider", i) + } + + response, err := r.client.VaultSecrets.CreateIntegration(&secret_service.CreateIntegrationParams{ + Body: &secretmodels.SecretServiceCreateIntegrationBody{ + Name: integration.Name.ValueString(), + Provider: integration.Provider.ValueString(), + Capabilities: integration.capabilities, + AwsAccessKeys: integration.awsAccessKeys, + AwsFederatedWorkloadIdentity: integration.awsFederatedWorkloadIdentity, + AzureClientSecret: integration.azureClientSecret, + AzureFederatedWorkloadIdentity: integration.azureFederatedWorkloadIdentity, + ConfluentStaticCredentials: integration.confluentStaticCredentials, + GcpServiceAccountKey: integration.gcpServiceAccountKey, + GcpFederatedWorkloadIdentity: integration.gcpFederatedWorkloadIdentity, + MongoDbAtlasStaticCredentials: integration.mongoDBAtlasStaticCredentials, + TwilioStaticCredentials: integration.twilioStaticCredentials, + }, + OrganizationID: integration.OrganizationID.ValueString(), + ProjectID: integration.ProjectID.ValueString(), + }, nil) + if err != nil && !clients.IsResponseCodeNotFound(err) { + return nil, err + } + if response == nil || response.Payload == nil { + return nil, nil + } + return response.Payload.Integration, nil + })...) +} + +func (r *resourceVaultSecretsIntegration) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + resp.Diagnostics.Append(decorateOperation[*Integration](ctx, r.client, &resp.State, req.Plan.Get, "updating", func(i hvsResource) (any, error) { + integration, ok := i.(*Integration) + if !ok { + return nil, fmt.Errorf("invalid integration type, expected *Integration, got: %T, this is a bug on the provider", i) + } + + response, err := r.client.VaultSecrets.UpdateIntegration(&secret_service.UpdateIntegrationParams{ + Body: &secretmodels.SecretServiceUpdateIntegrationBody{ + Provider: integration.Provider.ValueString(), + Capabilities: integration.capabilities, + AwsAccessKeys: integration.awsAccessKeys, + AwsFederatedWorkloadIdentity: integration.awsFederatedWorkloadIdentity, + AzureClientSecret: integration.azureClientSecret, + AzureFederatedWorkloadIdentity: integration.azureFederatedWorkloadIdentity, + ConfluentStaticCredentials: integration.confluentStaticCredentials, + GcpServiceAccountKey: integration.gcpServiceAccountKey, + GcpFederatedWorkloadIdentity: integration.gcpFederatedWorkloadIdentity, + MongoDbAtlasStaticCredentials: integration.mongoDBAtlasStaticCredentials, + TwilioStaticCredentials: integration.twilioStaticCredentials, + }, + Name: integration.Name.ValueString(), + OrganizationID: integration.OrganizationID.ValueString(), + ProjectID: integration.ProjectID.ValueString(), + }, nil) + if err != nil && !clients.IsResponseCodeNotFound(err) { + return nil, err + } + if response == nil || response.Payload == nil { + return nil, nil + } + return response.Payload.Integration, nil + })...) +} + +func (r *resourceVaultSecretsIntegration) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + resp.Diagnostics.Append(decorateOperation[*Integration](ctx, r.client, &resp.State, req.State.Get, "deleting", func(i hvsResource) (any, error) { + integration, ok := i.(*Integration) + if !ok { + return nil, fmt.Errorf("invalid integration type, expected *Integration, got: %T, this is a bug on the provider", i) + } + + _, err := r.client.VaultSecrets.DeleteIntegration( + secret_service.NewDeleteIntegrationParamsWithContext(ctx). + WithOrganizationID(integration.OrganizationID.ValueString()). + WithProjectID(integration.ProjectID.ValueString()). + WithName(integration.Name.ValueString()), nil) + if err != nil && !clients.IsResponseCodeNotFound(err) { + return nil, err + } + return nil, nil + })...) +} + +func (r *resourceVaultSecretsIntegration) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + // The Vault Secrets API does not return sensitive values like the secret access key, so they will be initialized to an empty value + // It means the first plan/apply after a successful import will always show a diff for the secret access key + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("organization_id"), r.client.Config.OrganizationID)...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), r.client.Config.ProjectID)...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("name"), req.ID)...) +} + +var _ hvsResource = &Integration{} + +func (i *Integration) projectID() types.String { + return i.ProjectID +} + +func (i *Integration) initModel(ctx context.Context, orgID, projID string) diag.Diagnostics { + // Init fields that depend on the Terraform provider configuration + i.OrganizationID = types.StringValue(orgID) + i.ProjectID = types.StringValue(projID) + + // Init the HVS domain models from the Terraform domain models + var capabilities []types.String + diags := i.Capabilities.ElementsAs(ctx, &capabilities, false) + if diags.HasError() { + return diags + } + for _, c := range capabilities { + i.capabilities = append(i.capabilities, secretmodels.Secrets20231128Capability(c.ValueString()).Pointer()) + } + + if !i.AwsAccessKeys.IsNull() { + ak := accessKeys{} + diags = i.AwsAccessKeys.As(ctx, &ak, basetypes.ObjectAsOptions{}) + if diags.HasError() { + return diags + } + + i.awsAccessKeys = &secretmodels.Secrets20231128AwsAccessKeysRequest{ + AccessKeyID: ak.AccessKeyID.ValueString(), + SecretAccessKey: ak.SecretAccessKey.ValueString(), + } + } + + if !i.AwsFederatedWorkloadIdentity.IsNull() { + fwi := awsFederatedWorkloadIdentity{} + diags = i.AwsFederatedWorkloadIdentity.As(ctx, &fwi, basetypes.ObjectAsOptions{}) + if diags.HasError() { + return diags + } + + i.awsFederatedWorkloadIdentity = &secretmodels.Secrets20231128AwsFederatedWorkloadIdentityRequest{ + RoleArn: fwi.RoleARN.ValueString(), + Audience: fwi.Audience.ValueString(), + } + } + + if !i.AzureClientSecret.IsNull() { + cs := clientSecret{} + diags = i.AzureClientSecret.As(ctx, &cs, basetypes.ObjectAsOptions{}) + if diags.HasError() { + return diags + } + + i.azureClientSecret = &secretmodels.Secrets20231128AzureClientSecretRequest{ + TenantID: cs.TenantID.ValueString(), + ClientID: cs.ClientID.ValueString(), + ClientSecret: cs.ClientSecret.ValueString(), + } + } + + if !i.AzureFederatedWorkloadIdentity.IsNull() { + fwi := azureFederatedWorkloadIdentity{} + diags = i.AzureFederatedWorkloadIdentity.As(ctx, &fwi, basetypes.ObjectAsOptions{}) + if diags.HasError() { + return diags + } + + i.azureFederatedWorkloadIdentity = &secretmodels.Secrets20231128AzureFederatedWorkloadIdentityRequest{ + Audience: fwi.Audience.ValueString(), + TenantID: fwi.TenantID.ValueString(), + ClientID: fwi.ClientID.ValueString(), + } + } + + if !i.ConfluentStaticCredentialDetails.IsNull() { + scd := confluentStaticCredentialDetails{} + diags = i.ConfluentStaticCredentialDetails.As(ctx, &scd, basetypes.ObjectAsOptions{}) + if diags.HasError() { + return diags + } + + i.confluentStaticCredentials = &secretmodels.Secrets20231128ConfluentStaticCredentialsRequest{ + CloudAPIKeyID: scd.CloudAPIKeyID.ValueString(), + CloudAPISecret: scd.CloudAPISecret.ValueString(), + } + } + + if !i.GcpServiceAccountKey.IsNull() { + sa := serviceAccountKey{} + diags = i.GcpServiceAccountKey.As(ctx, &sa, basetypes.ObjectAsOptions{}) + if diags.HasError() { + return diags + } + + i.gcpServiceAccountKey = &secretmodels.Secrets20231128GcpServiceAccountKeyRequest{ + Credentials: sa.Credentials.ValueString(), + } + } + + if !i.GcpFederatedWorkloadIdentity.IsNull() { + fwi := gcpFederatedWorkloadIdentity{} + diags = i.GcpFederatedWorkloadIdentity.As(ctx, &fwi, basetypes.ObjectAsOptions{}) + if diags.HasError() { + return diags + } + + i.gcpFederatedWorkloadIdentity = &secretmodels.Secrets20231128GcpFederatedWorkloadIdentityRequest{ + Audience: fwi.Audience.ValueString(), + ServiceAccountEmail: fwi.ServiceAccountEmail.ValueString(), + } + } + + if !i.MongoDBAtlasStaticCredentials.IsNull() { + scd := mongoDBAtlasStaticCredentialDetails{} + diags = i.MongoDBAtlasStaticCredentials.As(ctx, &scd, basetypes.ObjectAsOptions{}) + if diags.HasError() { + return diags + } + + i.mongoDBAtlasStaticCredentials = &secretmodels.Secrets20231128MongoDBAtlasStaticCredentialsRequest{ + APIPublicKey: scd.APIPublicKey.ValueString(), + APIPrivateKey: scd.APIPrivateKey.ValueString(), + } + } + + if !i.TwilioStaticCredentials.IsNull() { + scd := staticCredentialDetails{} + diags = i.TwilioStaticCredentials.As(ctx, &scd, basetypes.ObjectAsOptions{}) + if diags.HasError() { + return diags + } + + i.twilioStaticCredentials = &secretmodels.Secrets20231128TwilioStaticCredentialsRequest{ + AccountSid: scd.AccountSID.ValueString(), + APIKeySecret: scd.APIKeySecret.ValueString(), + APIKeySid: scd.APIKeySID.ValueString(), + } + } + + return diag.Diagnostics{} +} + +func (i *Integration) fromModel(ctx context.Context, orgID, projID string, model any) diag.Diagnostics { + diags := diag.Diagnostics{} + + integrationModel, ok := model.(*secretmodels.Secrets20231128Integration) + if !ok { + diags.AddError("Invalid model type, this is a bug on the provider.", fmt.Sprintf("Expected *secretmodels.Secrets20231128Integration, got: %T", model)) + return diags + } + + i.OrganizationID = types.StringValue(orgID) + i.ProjectID = types.StringValue(projID) + i.ResourceID = types.StringValue(integrationModel.ResourceID) + i.ResourceName = types.StringValue(integrationModel.ResourceName) + i.Name = types.StringValue(integrationModel.Name) + i.Provider = types.StringValue(integrationModel.Provider) + + var values []attr.Value + for _, c := range integrationModel.Capabilities { + values = append(values, types.StringValue(string(*c))) + } + i.Capabilities, diags = types.SetValue(types.StringType, values) + if diags.HasError() { + return diags + } + + if integrationModel.AwsAccessKeys != nil { + secretAccessKey := "" + if i.awsAccessKeys != nil { + secretAccessKey = i.awsAccessKeys.SecretAccessKey + } + + i.AwsAccessKeys, diags = types.ObjectValue(i.AwsAccessKeys.AttributeTypes(ctx), map[string]attr.Value{ + "access_key_id": types.StringValue(integrationModel.AwsAccessKeys.AccessKeyID), + "secret_access_key": types.StringValue(secretAccessKey), + }) + if diags.HasError() { + return diags + } + } + + if integrationModel.AwsFederatedWorkloadIdentity != nil { + i.AwsFederatedWorkloadIdentity, diags = types.ObjectValue(i.AwsFederatedWorkloadIdentity.AttributeTypes(ctx), map[string]attr.Value{ + "role_arn": types.StringValue(integrationModel.AwsFederatedWorkloadIdentity.RoleArn), + "audience": types.StringValue(integrationModel.AwsFederatedWorkloadIdentity.Audience), + }) + if diags.HasError() { + return diags + } + } + + if integrationModel.AzureClientSecret != nil { + clientSecret := "" + if i.azureClientSecret != nil { + clientSecret = i.azureClientSecret.ClientSecret + } + i.AzureClientSecret, diags = types.ObjectValue(i.AzureClientSecret.AttributeTypes(ctx), map[string]attr.Value{ + "tenant_id": types.StringValue(integrationModel.AzureClientSecret.TenantID), + "client_id": types.StringValue(integrationModel.AzureClientSecret.ClientID), + "client_secret": types.StringValue(clientSecret), + }) + if diags.HasError() { + return diags + } + } + + if integrationModel.AzureFederatedWorkloadIdentity != nil { + i.AzureFederatedWorkloadIdentity, diags = types.ObjectValue(i.AzureFederatedWorkloadIdentity.AttributeTypes(ctx), map[string]attr.Value{ + "tenant_id": types.StringValue(integrationModel.AzureFederatedWorkloadIdentity.TenantID), + "client_id": types.StringValue(integrationModel.AzureFederatedWorkloadIdentity.ClientID), + "audience": types.StringValue(integrationModel.AzureFederatedWorkloadIdentity.Audience), + }) + if diags.HasError() { + return diags + } + } + + if integrationModel.ConfluentStaticCredentials != nil { + cloudAPISecret := "" + if i.confluentStaticCredentials != nil { + cloudAPISecret = i.confluentStaticCredentials.CloudAPISecret + } + + i.ConfluentStaticCredentialDetails, diags = types.ObjectValue(i.ConfluentStaticCredentialDetails.AttributeTypes(ctx), map[string]attr.Value{ + "cloud_api_key_id": types.StringValue(integrationModel.ConfluentStaticCredentials.CloudAPIKeyID), + "cloud_api_secret": types.StringValue(cloudAPISecret), + }) + if diags.HasError() { + return diags + } + } + + if integrationModel.GcpServiceAccountKey != nil { + credentials := "" + if i.gcpServiceAccountKey != nil { + credentials = i.gcpServiceAccountKey.Credentials + } + + i.GcpServiceAccountKey, diags = types.ObjectValue(i.GcpServiceAccountKey.AttributeTypes(ctx), map[string]attr.Value{ + "credentials": types.StringValue(credentials), + "project_id": types.StringValue(integrationModel.GcpServiceAccountKey.ProjectID), + "client_email": types.StringValue(integrationModel.GcpServiceAccountKey.ClientEmail), + }) + if diags.HasError() { + return diags + } + } + + if integrationModel.GcpFederatedWorkloadIdentity != nil { + i.GcpFederatedWorkloadIdentity, diags = types.ObjectValue(i.GcpFederatedWorkloadIdentity.AttributeTypes(ctx), map[string]attr.Value{ + "service_account_email": types.StringValue(integrationModel.GcpFederatedWorkloadIdentity.ServiceAccountEmail), + "audience": types.StringValue(integrationModel.GcpFederatedWorkloadIdentity.Audience), + }) + if diags.HasError() { + return diags + } + } + + if integrationModel.MongoDbAtlasStaticCredentials != nil { + apiPrivateKey := "" + if i.mongoDBAtlasStaticCredentials != nil { + apiPrivateKey = i.mongoDBAtlasStaticCredentials.APIPrivateKey + } + + i.MongoDBAtlasStaticCredentials, diags = types.ObjectValue(i.MongoDBAtlasStaticCredentials.AttributeTypes(ctx), map[string]attr.Value{ + "api_public_key": types.StringValue(integrationModel.MongoDbAtlasStaticCredentials.APIPublicKey), + "api_private_key": types.StringValue(apiPrivateKey), + }) + if diags.HasError() { + return diags + } + } + + if integrationModel.TwilioStaticCredentials != nil { + apiKeySecret := "" + if i.twilioStaticCredentials != nil { + apiKeySecret = i.twilioStaticCredentials.APIKeySecret + } + + i.TwilioStaticCredentials, diags = types.ObjectValue(i.TwilioStaticCredentials.AttributeTypes(ctx), map[string]attr.Value{ + "account_sid": types.StringValue(integrationModel.TwilioStaticCredentials.AccountSid), + "api_key_sid": types.StringValue(integrationModel.TwilioStaticCredentials.APIKeySid), + "api_key_secret": types.StringValue(apiKeySecret), + }) + if diags.HasError() { + return diags + } + } + + return diags +} diff --git a/internal/provider/vaultsecrets/resource_vault_secrets_integration_aws.go b/internal/provider/vaultsecrets/resource_vault_secrets_integration_aws_deprecated.go similarity index 100% rename from internal/provider/vaultsecrets/resource_vault_secrets_integration_aws.go rename to internal/provider/vaultsecrets/resource_vault_secrets_integration_aws_deprecated.go diff --git a/internal/provider/vaultsecrets/resource_vault_secrets_integration_aws_test.go b/internal/provider/vaultsecrets/resource_vault_secrets_integration_aws_test.go index 724dbd35a..172da3100 100644 --- a/internal/provider/vaultsecrets/resource_vault_secrets_integration_aws_test.go +++ b/internal/provider/vaultsecrets/resource_vault_secrets_integration_aws_test.go @@ -12,6 +12,7 @@ import ( secretmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-vault-secrets/stable/2023-11-28/models" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-hcp/internal/clients" "github.com/hashicorp/terraform-provider-hcp/internal/provider/acctest" ) @@ -32,72 +33,78 @@ func TestAccVaultSecretsResourceIntegrationAWS(t *testing.T) { // Create initial integration with access keys { Config: fmt.Sprintf(` - resource "hcp_vault_secrets_integration_aws" "acc_test" { + resource "hcp_vault_secrets_integration" "acc_test" { name = %q capabilities = ["DYNAMIC", "ROTATION"] - access_keys = { + provider_type = "aws" + aws_access_keys = { access_key_id = %q secret_access_key = %q } }`, integrationName1, accessKeyID, secretAccessKey), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_aws.acc_test", "organization_id"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_aws.acc_test", "resource_id"), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_aws.acc_test", "resource_name"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "name", integrationName1), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "capabilities.#", "2"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "capabilities.0", "DYNAMIC"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "capabilities.1", "ROTATION"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "access_keys.access_key_id", accessKeyID), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "access_keys.secret_access_key", secretAccessKey), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "organization_id"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_id"), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_name"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "name", integrationName1), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.#", "2"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.0", "DYNAMIC"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.1", "ROTATION"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "provider_type", "aws"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "aws_access_keys.access_key_id", accessKeyID), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "aws_access_keys.secret_access_key", secretAccessKey), ), }, // Changing the name forces a recreation { Config: fmt.Sprintf(` - resource "hcp_vault_secrets_integration_aws" "acc_test" { + resource "hcp_vault_secrets_integration" "acc_test" { name = %q capabilities = ["DYNAMIC", "ROTATION"] - access_keys = { + provider_type = "aws" + aws_access_keys = { access_key_id = %q secret_access_key = %q } }`, integrationName2, accessKeyID, secretAccessKey), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_aws.acc_test", "organization_id"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_aws.acc_test", "resource_id"), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_aws.acc_test", "resource_name"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "name", integrationName2), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "capabilities.#", "2"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "capabilities.0", "DYNAMIC"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "capabilities.1", "ROTATION"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "access_keys.access_key_id", accessKeyID), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "access_keys.secret_access_key", secretAccessKey), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "organization_id"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_id"), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_name"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "name", integrationName2), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.#", "2"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.0", "DYNAMIC"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.1", "ROTATION"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "provider_type", "aws"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "aws_access_keys.access_key_id", accessKeyID), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "aws_access_keys.secret_access_key", secretAccessKey), ), }, // Modifying mutable fields causes an update { Config: fmt.Sprintf(` - resource "hcp_vault_secrets_integration_aws" "acc_test" { + resource "hcp_vault_secrets_integration" "acc_test" { name = %q capabilities = ["DYNAMIC"] - federated_workload_identity = { + provider_type = "aws" + aws_federated_workload_identity = { role_arn = %q audience = %q } }`, integrationName2, roleArn, audience), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_aws.acc_test", "organization_id"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_aws.acc_test", "resource_id"), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_aws.acc_test", "resource_name"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "name", integrationName2), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "capabilities.#", "1"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "capabilities.0", "DYNAMIC"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "federated_workload_identity.role_arn", roleArn), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "federated_workload_identity.audience", audience), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "organization_id"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_id"), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_name"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "name", integrationName2), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.#", "1"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.0", "DYNAMIC"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "provider_type", "aws"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "aws_federated_workload_identity.role_arn", roleArn), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "aws_federated_workload_identity.audience", audience), ), }, // Deleting the integration out of band causes a recreation @@ -106,24 +113,26 @@ func TestAccVaultSecretsResourceIntegrationAWS(t *testing.T) { deleteTestAwsIntegration(t, integrationName2) }, Config: fmt.Sprintf(` - resource "hcp_vault_secrets_integration_aws" "acc_test" { + resource "hcp_vault_secrets_integration" "acc_test" { name = %q capabilities = ["DYNAMIC"] - federated_workload_identity = { + provider_type = "aws" + aws_federated_workload_identity = { role_arn = %q audience = %q } }`, integrationName2, roleArn, audience), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_aws.acc_test", "organization_id"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_aws.acc_test", "resource_id"), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_aws.acc_test", "resource_name"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "name", integrationName2), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "capabilities.#", "1"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "capabilities.0", "DYNAMIC"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "federated_workload_identity.role_arn", roleArn), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "federated_workload_identity.audience", audience), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "organization_id"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_id"), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_name"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "name", integrationName2), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.#", "1"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.0", "DYNAMIC"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "provider_type", "aws"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "aws_federated_workload_identity.role_arn", roleArn), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "aws_federated_workload_identity.audience", audience), ), PlanOnly: true, ExpectNonEmptyPlan: true, @@ -134,26 +143,28 @@ func TestAccVaultSecretsResourceIntegrationAWS(t *testing.T) { createTestAwsIntegration(t, integrationName2, roleArn, audience, []*secretmodels.Secrets20231128Capability{secretmodels.Secrets20231128CapabilityDYNAMIC.Pointer()}) }, Config: fmt.Sprintf(` - resource "hcp_vault_secrets_integration_aws" "acc_test" { + resource "hcp_vault_secrets_integration" "acc_test" { name = %q capabilities = ["DYNAMIC"] - federated_workload_identity = { + provider_type = "aws" + aws_federated_workload_identity = { role_arn = %q audience = %q } }`, integrationName2, roleArn, audience), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_aws.acc_test", "organization_id"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_aws.acc_test", "resource_id"), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_aws.acc_test", "resource_name"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "name", integrationName2), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "capabilities.#", "1"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "capabilities.0", "DYNAMIC"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "federated_workload_identity.role_arn", roleArn), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_aws.acc_test", "federated_workload_identity.audience", audience), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "organization_id"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_id"), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_name"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "name", integrationName2), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.#", "1"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.0", "DYNAMIC"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "provider_type", "aws"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "aws_federated_workload_identity.role_arn", roleArn), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "aws_federated_workload_identity.audience", audience), ), - ResourceName: "hcp_vault_secrets_integration_aws.acc_test", + ResourceName: "hcp_vault_secrets_integration.acc_test", ImportStateId: integrationName2, ImportState: true, }, diff --git a/internal/provider/vaultsecrets/resource_vault_secrets_integration_azure.go b/internal/provider/vaultsecrets/resource_vault_secrets_integration_azure_deprecated.go similarity index 100% rename from internal/provider/vaultsecrets/resource_vault_secrets_integration_azure.go rename to internal/provider/vaultsecrets/resource_vault_secrets_integration_azure_deprecated.go diff --git a/internal/provider/vaultsecrets/resource_vault_secrets_integration_azure_test.go b/internal/provider/vaultsecrets/resource_vault_secrets_integration_azure_test.go index 875e0342a..d98e62e39 100644 --- a/internal/provider/vaultsecrets/resource_vault_secrets_integration_azure_test.go +++ b/internal/provider/vaultsecrets/resource_vault_secrets_integration_azure_test.go @@ -12,6 +12,7 @@ import ( secretmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-vault-secrets/stable/2023-11-28/models" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-hcp/internal/clients" "github.com/hashicorp/terraform-provider-hcp/internal/provider/acctest" ) @@ -98,7 +99,7 @@ func TestAccVaultSecretsResourceIntegrationAzure(t *testing.T) { Check: resource.ComposeTestCheckFunc( azureCheckFederatedIdentityFuncs(integrationName2, clientID, tenantID, audience)..., ), - ResourceName: "hcp_vault_secrets_integration_azure.acc_test", + ResourceName: "hcp_vault_secrets_integration.acc_test", ImportStateId: integrationName2, ImportState: true, PlanOnly: true, @@ -118,10 +119,11 @@ func TestAccVaultSecretsResourceIntegrationAzure(t *testing.T) { func azureClientSecretConfig(integrationName, clientID, tenantID, clientSecret string) string { return fmt.Sprintf(` - resource "hcp_vault_secrets_integration_azure" "acc_test" { + resource "hcp_vault_secrets_integration" "acc_test" { name = %q capabilities = ["ROTATION"] - client_secret = { + provider_type = "azure" + azure_client_secret = { tenant_id = %q client_id = %q client_secret = %q @@ -131,10 +133,11 @@ func azureClientSecretConfig(integrationName, clientID, tenantID, clientSecret s func azureFederatedIdentityConfig(integrationName, clientID, tenantID, audience string) string { return fmt.Sprintf(` - resource "hcp_vault_secrets_integration_azure" "acc_test" { + resource "hcp_vault_secrets_integration" "acc_test" { name = %q capabilities = ["ROTATION"] - federated_workload_identity = { + provider_type = "azure" + azure_federated_workload_identity = { tenant_id = %q client_id = %q audience = %q @@ -144,31 +147,33 @@ func azureFederatedIdentityConfig(integrationName, clientID, tenantID, audience func azureCheckClientSecretKeyFuncs(integrationName, clientID, tenantID, clientSecret string) []resource.TestCheckFunc { return []resource.TestCheckFunc{ - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_azure.acc_test", "organization_id"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_azure.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_azure.acc_test", "resource_id"), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_azure.acc_test", "resource_name"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_azure.acc_test", "name", integrationName), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_azure.acc_test", "capabilities.#", "1"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_azure.acc_test", "capabilities.0", "ROTATION"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_azure.acc_test", "client_secret.client_id", clientID), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_azure.acc_test", "client_secret.tenant_id", tenantID), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_azure.acc_test", "client_secret.client_secret", clientSecret), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "organization_id"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_id"), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_name"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "name", integrationName), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.#", "1"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.0", "ROTATION"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "provider_type", "azure"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "azure_client_secret.client_id", clientID), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "azure_client_secret.tenant_id", tenantID), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "azure_client_secret.client_secret", clientSecret), } } func azureCheckFederatedIdentityFuncs(integrationName, clientID, tenantID, audience string) []resource.TestCheckFunc { return []resource.TestCheckFunc{ - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_azure.acc_test", "organization_id"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_azure.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_azure.acc_test", "resource_id"), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_azure.acc_test", "resource_name"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_azure.acc_test", "name", integrationName), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_azure.acc_test", "capabilities.#", "1"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_azure.acc_test", "capabilities.0", "ROTATION"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_azure.acc_test", "federated_workload_identity.audience", audience), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_azure.acc_test", "federated_workload_identity.tenant_id", tenantID), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_azure.acc_test", "federated_workload_identity.client_id", clientID), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "organization_id"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_id"), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_name"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "name", integrationName), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.#", "1"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.0", "ROTATION"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "provider_type", "azure"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "azure_federated_workload_identity.audience", audience), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "azure_federated_workload_identity.tenant_id", tenantID), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "azure_federated_workload_identity.client_id", clientID), } } diff --git a/internal/provider/vaultsecrets/resource_vault_secrets_integration_confluent.go b/internal/provider/vaultsecrets/resource_vault_secrets_integration_confluent_deprecated.go similarity index 99% rename from internal/provider/vaultsecrets/resource_vault_secrets_integration_confluent.go rename to internal/provider/vaultsecrets/resource_vault_secrets_integration_confluent_deprecated.go index 548d5c2f8..e338608c5 100644 --- a/internal/provider/vaultsecrets/resource_vault_secrets_integration_confluent.go +++ b/internal/provider/vaultsecrets/resource_vault_secrets_integration_confluent_deprecated.go @@ -16,9 +16,10 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "golang.org/x/exp/maps" + "github.com/hashicorp/terraform-provider-hcp/internal/clients" "github.com/hashicorp/terraform-provider-hcp/internal/provider/modifiers" - "golang.org/x/exp/maps" ) type IntegrationConfluent struct { diff --git a/internal/provider/vaultsecrets/resource_vault_secrets_integration_confluent_test.go b/internal/provider/vaultsecrets/resource_vault_secrets_integration_confluent_test.go index 97042935b..f96a8d109 100644 --- a/internal/provider/vaultsecrets/resource_vault_secrets_integration_confluent_test.go +++ b/internal/provider/vaultsecrets/resource_vault_secrets_integration_confluent_test.go @@ -12,6 +12,7 @@ import ( secretmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-vault-secrets/stable/2023-11-28/models" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-hcp/internal/clients" "github.com/hashicorp/terraform-provider-hcp/internal/provider/acctest" ) @@ -87,7 +88,7 @@ func TestAccVaultSecretsResourceIntegrationConfluent(t *testing.T) { Check: resource.ComposeTestCheckFunc( confluentCheckFuncs(integrationName2, cloudAPIKeyID, cloudAPISecret)..., ), - ResourceName: "hcp_vault_secrets_integration_confluent.acc_test", + ResourceName: "hcp_vault_secrets_integration.acc_test", ImportStateId: integrationName2, ImportState: true, }, @@ -106,10 +107,11 @@ func TestAccVaultSecretsResourceIntegrationConfluent(t *testing.T) { func confluentConfig(integrationName, cloudAPIKeyID, cloudAPISecret string) string { return fmt.Sprintf(` - resource "hcp_vault_secrets_integration_confluent" "acc_test" { + resource "hcp_vault_secrets_integration" "acc_test" { name = %q capabilities = ["ROTATION"] - static_credential_details = { + provider_type = "confluent" + confluent_static_credentials = { cloud_api_key_id = %q cloud_api_secret = %q } @@ -118,15 +120,16 @@ func confluentConfig(integrationName, cloudAPIKeyID, cloudAPISecret string) stri func confluentCheckFuncs(integrationName, cloudAPIKeyID, cloudAPISecret string) []resource.TestCheckFunc { return []resource.TestCheckFunc{ - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_confluent.acc_test", "organization_id"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_confluent.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_confluent.acc_test", "resource_id"), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_confluent.acc_test", "resource_name"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_confluent.acc_test", "name", integrationName), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_confluent.acc_test", "capabilities.#", "1"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_confluent.acc_test", "capabilities.0", "ROTATION"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_confluent.acc_test", "static_credential_details.cloud_api_secret", cloudAPISecret), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_confluent.acc_test", "static_credential_details.cloud_api_key_id", cloudAPIKeyID), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "organization_id"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_id"), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_name"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "name", integrationName), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.#", "1"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.0", "ROTATION"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "provider_type", "confluent"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "confluent_static_credentials.cloud_api_secret", cloudAPISecret), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "confluent_static_credentials.cloud_api_key_id", cloudAPIKeyID), } } diff --git a/internal/provider/vaultsecrets/resource_vault_secrets_integration_gcp.go b/internal/provider/vaultsecrets/resource_vault_secrets_integration_gcp_deprecated.go similarity index 100% rename from internal/provider/vaultsecrets/resource_vault_secrets_integration_gcp.go rename to internal/provider/vaultsecrets/resource_vault_secrets_integration_gcp_deprecated.go diff --git a/internal/provider/vaultsecrets/resource_vault_secrets_integration_gcp_test.go b/internal/provider/vaultsecrets/resource_vault_secrets_integration_gcp_test.go index 0bb681452..b7aabede4 100644 --- a/internal/provider/vaultsecrets/resource_vault_secrets_integration_gcp_test.go +++ b/internal/provider/vaultsecrets/resource_vault_secrets_integration_gcp_test.go @@ -12,6 +12,7 @@ import ( secretmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-vault-secrets/stable/2023-11-28/models" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-hcp/internal/clients" "github.com/hashicorp/terraform-provider-hcp/internal/provider/acctest" ) @@ -97,7 +98,7 @@ func TestAccVaultSecretsResourceIntegrationGCP(t *testing.T) { Check: resource.ComposeTestCheckFunc( gcpCheckFederatedIdentityFuncs(integrationName2, audience, serviceAccountEmail)..., ), - ResourceName: "hcp_vault_secrets_integration_gcp.acc_test", + ResourceName: "hcp_vault_secrets_integration.acc_test", ImportStateId: integrationName2, ImportState: true, }, @@ -116,10 +117,11 @@ func TestAccVaultSecretsResourceIntegrationGCP(t *testing.T) { func gcpServiceAccountConfig(integrationName, serviceAccountKey string) string { return fmt.Sprintf(` - resource "hcp_vault_secrets_integration_gcp" "acc_test" { + resource "hcp_vault_secrets_integration" "acc_test" { name = %q capabilities = ["ROTATION"] - service_account_key = { + provider_type = "gcp" + gcp_service_account_key = { credentials = %q } }`, integrationName, serviceAccountKey) @@ -127,10 +129,11 @@ func gcpServiceAccountConfig(integrationName, serviceAccountKey string) string { func gcpFederatedIdentityConfig(integrationName, serviceAccountEmail, audience string) string { return fmt.Sprintf(` - resource "hcp_vault_secrets_integration_gcp" "acc_test" { + resource "hcp_vault_secrets_integration" "acc_test" { name = %q capabilities = ["DYNAMIC"] - federated_workload_identity = { + provider_type = "azure" + gcp_federated_workload_identity = { service_account_email = %q audience = %q } @@ -139,30 +142,32 @@ func gcpFederatedIdentityConfig(integrationName, serviceAccountEmail, audience s func gcpCheckServiceAccountKeyFuncs(integrationName, clientEmail, credentials, projectID string) []resource.TestCheckFunc { return []resource.TestCheckFunc{ - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_gcp.acc_test", "organization_id"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_gcp.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_gcp.acc_test", "resource_id"), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_gcp.acc_test", "resource_name"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_gcp.acc_test", "name", integrationName), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_gcp.acc_test", "capabilities.#", "1"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_gcp.acc_test", "capabilities.0", "ROTATION"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_gcp.acc_test", "service_account_key.client_email", clientEmail), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_gcp.acc_test", "service_account_key.credentials", credentials), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_gcp.acc_test", "service_account_key.project_id", projectID), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "organization_id"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_id"), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_name"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "name", integrationName), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.#", "1"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.0", "ROTATION"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "provider_type", "gcp"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "gcp_service_account_key.client_email", clientEmail), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "gcp_service_account_key.credentials", credentials), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "gcp_service_account_key.project_id", projectID), } } func gcpCheckFederatedIdentityFuncs(integrationName, audience, serviceAccountEmail string) []resource.TestCheckFunc { return []resource.TestCheckFunc{ - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_gcp.acc_test", "organization_id"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_gcp.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_gcp.acc_test", "resource_id"), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_gcp.acc_test", "resource_name"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_gcp.acc_test", "name", integrationName), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_gcp.acc_test", "capabilities.#", "1"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_gcp.acc_test", "capabilities.0", "DYNAMIC"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_gcp.acc_test", "federated_workload_identity.audience", audience), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_gcp.acc_test", "federated_workload_identity.service_account_email", serviceAccountEmail), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "organization_id"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_id"), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_name"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "name", integrationName), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.#", "1"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.0", "DYNAMIC"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "provider_type", "gcp"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "gcp_federated_workload_identity.audience", audience), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "gcp_federated_workload_identity.service_account_email", serviceAccountEmail), } } diff --git a/internal/provider/vaultsecrets/resource_vault_secrets_integration_mongodbatlas.go b/internal/provider/vaultsecrets/resource_vault_secrets_integration_mongodbatlas_deprecated.go similarity index 100% rename from internal/provider/vaultsecrets/resource_vault_secrets_integration_mongodbatlas.go rename to internal/provider/vaultsecrets/resource_vault_secrets_integration_mongodbatlas_deprecated.go diff --git a/internal/provider/vaultsecrets/resource_vault_secrets_integration_mongodbatlas_test.go b/internal/provider/vaultsecrets/resource_vault_secrets_integration_mongodbatlas_test.go index a4f6cde67..e03f3110f 100644 --- a/internal/provider/vaultsecrets/resource_vault_secrets_integration_mongodbatlas_test.go +++ b/internal/provider/vaultsecrets/resource_vault_secrets_integration_mongodbatlas_test.go @@ -12,6 +12,7 @@ import ( secretmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-vault-secrets/stable/2023-11-28/models" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-hcp/internal/clients" "github.com/hashicorp/terraform-provider-hcp/internal/provider/acctest" ) @@ -94,7 +95,7 @@ func TestAccVaultSecretsResourceIntegrationMongoDBAtlas(t *testing.T) { Check: resource.ComposeTestCheckFunc( mongoDBAtlasCheckFuncs(integrationName2, publicKey, privateKey)..., ), - ResourceName: "hcp_vault_secrets_integration_mongodbatlas.acc_test", + ResourceName: "hcp_vault_secrets_integration.acc_test", ImportStateId: integrationName2, ImportState: true, }, @@ -113,10 +114,11 @@ func TestAccVaultSecretsResourceIntegrationMongoDBAtlas(t *testing.T) { func mongoDBAtlasConfig(integrationName, apiPublicKey, apiPrivateKey string) string { return fmt.Sprintf(` - resource "hcp_vault_secrets_integration_mongodbatlas" "acc_test"{ + resource "hcp_vault_secrets_integration" "acc_test"{ name = %q capabilities = ["ROTATION"] - static_credential_details = { + provider_type = "mongodb-atlas" + mongodb_atlas_static_credentials = { api_public_key = %q api_private_key = %q } @@ -125,15 +127,16 @@ func mongoDBAtlasConfig(integrationName, apiPublicKey, apiPrivateKey string) str func mongoDBAtlasCheckFuncs(integrationName, apiPublicKey, apiPrivateKey string) []resource.TestCheckFunc { return []resource.TestCheckFunc{ - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_mongodbatlas.acc_test", "organization_id"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_mongodbatlas.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_mongodbatlas.acc_test", "resource_id"), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_mongodbatlas.acc_test", "resource_name"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_mongodbatlas.acc_test", "name", integrationName), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_mongodbatlas.acc_test", "capabilities.#", "1"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_mongodbatlas.acc_test", "capabilities.0", "ROTATION"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_mongodbatlas.acc_test", "static_credential_details.api_public_key", apiPublicKey), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_mongodbatlas.acc_test", "static_credential_details.api_private_key", apiPrivateKey), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "organization_id"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_id"), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_name"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "name", integrationName), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.#", "1"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.0", "ROTATION"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "provider_type", "mongodb-atlas"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "mongodb_atlas_static_credentials.api_public_key", apiPublicKey), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "mongodb_atlas_static_credentials.api_private_key", apiPrivateKey), } } diff --git a/internal/provider/vaultsecrets/resource_vault_secrets_integration_twilio.go b/internal/provider/vaultsecrets/resource_vault_secrets_integration_twilio_deprecated.go similarity index 99% rename from internal/provider/vaultsecrets/resource_vault_secrets_integration_twilio.go rename to internal/provider/vaultsecrets/resource_vault_secrets_integration_twilio_deprecated.go index efb5deaae..48a0324d1 100644 --- a/internal/provider/vaultsecrets/resource_vault_secrets_integration_twilio.go +++ b/internal/provider/vaultsecrets/resource_vault_secrets_integration_twilio_deprecated.go @@ -16,9 +16,10 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "golang.org/x/exp/maps" + "github.com/hashicorp/terraform-provider-hcp/internal/clients" "github.com/hashicorp/terraform-provider-hcp/internal/provider/modifiers" - "golang.org/x/exp/maps" ) type IntegrationTwilio struct { diff --git a/internal/provider/vaultsecrets/resource_vault_secrets_integration_twilio_test.go b/internal/provider/vaultsecrets/resource_vault_secrets_integration_twilio_test.go index 768d1e3a3..167a6fffb 100644 --- a/internal/provider/vaultsecrets/resource_vault_secrets_integration_twilio_test.go +++ b/internal/provider/vaultsecrets/resource_vault_secrets_integration_twilio_test.go @@ -12,6 +12,7 @@ import ( secretmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-vault-secrets/stable/2023-11-28/models" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-hcp/internal/clients" "github.com/hashicorp/terraform-provider-hcp/internal/provider/acctest" ) @@ -96,7 +97,7 @@ func TestAccVaultSecretsResourceIntegrationTwilio(t *testing.T) { Check: resource.ComposeTestCheckFunc( twilioCheckFuncs(integrationName2, accountSID, apiKeySID, apiKeySecret)..., ), - ResourceName: "hcp_vault_secrets_integration_twilio.acc_test", + ResourceName: "hcp_vault_secrets_integration.acc_test", ImportStateId: integrationName2, ImportState: true, }, @@ -115,10 +116,11 @@ func TestAccVaultSecretsResourceIntegrationTwilio(t *testing.T) { func twilioConfig(integrationName, accountSID, apiKeySID, apiKeySecret string) string { return fmt.Sprintf(` - resource "hcp_vault_secrets_integration_twilio" "acc_test" { + resource "hcp_vault_secrets_integration" "acc_test" { name = %q capabilities = ["ROTATION"] - static_credential_details = { + provider_type = "twilio" + twilio_static_credentials = { account_sid = %q api_key_sid = %q api_key_secret = %q @@ -128,16 +130,17 @@ func twilioConfig(integrationName, accountSID, apiKeySID, apiKeySecret string) s func twilioCheckFuncs(integrationName, accountSID, apiKeySID, apiKeySecret string) []resource.TestCheckFunc { return []resource.TestCheckFunc{ - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_twilio.acc_test", "organization_id"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_twilio.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_twilio.acc_test", "resource_id"), - resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration_twilio.acc_test", "resource_name"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_twilio.acc_test", "name", integrationName), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_twilio.acc_test", "capabilities.#", "1"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_twilio.acc_test", "capabilities.0", "ROTATION"), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_twilio.acc_test", "static_credential_details.account_sid", accountSID), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_twilio.acc_test", "static_credential_details.api_key_secret", apiKeySecret), - resource.TestCheckResourceAttr("hcp_vault_secrets_integration_twilio.acc_test", "static_credential_details.api_key_sid", apiKeySID), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "organization_id"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "project_id", os.Getenv("HCP_PROJECT_ID")), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_id"), + resource.TestCheckResourceAttrSet("hcp_vault_secrets_integration.acc_test", "resource_name"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "name", integrationName), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.#", "1"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "capabilities.0", "ROTATION"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "provider_type", "twilio"), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "twilio_static_credentials.account_sid", accountSID), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "twilio_static_credentials.api_key_secret", apiKeySecret), + resource.TestCheckResourceAttr("hcp_vault_secrets_integration.acc_test", "twilio_static_credentials.api_key_sid", apiKeySID), } } diff --git a/internal/provider/vaultsecrets/resource_vault_secrets_rotating_secret.go b/internal/provider/vaultsecrets/resource_vault_secrets_rotating_secret.go index 05e9fee98..589b2334c 100644 --- a/internal/provider/vaultsecrets/resource_vault_secrets_rotating_secret.go +++ b/internal/provider/vaultsecrets/resource_vault_secrets_rotating_secret.go @@ -19,9 +19,10 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "golang.org/x/exp/maps" + "github.com/hashicorp/terraform-provider-hcp/internal/clients" "github.com/hashicorp/terraform-provider-hcp/internal/provider/modifiers" - "golang.org/x/exp/maps" ) var exactlyOneRotatingSecretTypeFieldsValidator = objectvalidator.ExactlyOneOf( @@ -49,6 +50,7 @@ var rotatingSecretsImpl = map[Provider]rotatingSecret{ ProviderAWS: &awsRotatingSecret{}, ProviderGCP: &gcpRotatingSecret{}, ProviderMongoDBAtlas: &mongoDBAtlasRotatingSecret{}, + "mongodb_atlas": &mongoDBAtlasRotatingSecret{}, // The provider name changed to mongodb-atlas to fit with the HVS API, this is for backwards compatibility ProviderTwilio: &twilioRotatingSecret{}, ProviderConfluent: &confluentRotatingSecret{}, ProviderAzure: &azureRotatingSecret{}, diff --git a/internal/provider/vaultsecrets/vault_secrets_utils.go b/internal/provider/vaultsecrets/vault_secrets_utils.go index 83707569d..a68256765 100644 --- a/internal/provider/vaultsecrets/vault_secrets_utils.go +++ b/internal/provider/vaultsecrets/vault_secrets_utils.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-provider-hcp/internal/clients" ) @@ -23,17 +24,28 @@ type Provider string const ( ProviderAWS Provider = "aws" + ProviderAzure Provider = "azure" + ProviderConfluent Provider = "confluent" ProviderGCP Provider = "gcp" - ProviderMongoDBAtlas Provider = "mongodb_atlas" + ProviderMongoDBAtlas Provider = "mongodb-atlas" ProviderTwilio Provider = "twilio" - ProviderConfluent Provider = "confluent" - ProviderAzure Provider = "azure" ) func (p Provider) String() string { return string(p) } +func ProviderStrings() []string { + return []string{ + string(ProviderAWS), + string(ProviderAzure), + string(ProviderConfluent), + string(ProviderGCP), + string(ProviderMongoDBAtlas), + string(ProviderTwilio), + } +} + var ( secretNameValidator = stringvalidator.RegexMatches(regexp.MustCompile(`^[_\da-zA-Z]{3,36}$`), "must contain only letters, numbers or underscores", diff --git a/templates/resources/vault_secrets_integration.md.tmpl b/templates/resources/vault_secrets_integration.md.tmpl new file mode 100644 index 000000000..64e68f783 --- /dev/null +++ b/templates/resources/vault_secrets_integration.md.tmpl @@ -0,0 +1,22 @@ +--- +page_title: "{{.Type}} {{.Name}}" +subcategory: "HCP Vault Secrets" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +## Example Usage + +{{ tffile "examples/resources/hcp_vault_secrets_integration/resource.tf" }} + +{{ .SchemaMarkdown | trimspace }} + +## Import + +Import is supported using the following syntax: + +{{ codefile "shell" "examples/resources/hcp_vault_secrets_integration/import.sh" }} diff --git a/templates/resources/vault_secrets_integration_aws.md.tmpl b/templates/resources/vault_secrets_integration_aws.md.tmpl index a20cd424f..8f9da09f9 100644 --- a/templates/resources/vault_secrets_integration_aws.md.tmpl +++ b/templates/resources/vault_secrets_integration_aws.md.tmpl @@ -9,6 +9,8 @@ description: |- {{ .Description | trimspace }} +~> **Note:** This resource is deprecated, please use `hcp_vault_secrets_integration` instead. + ## Example Usage {{ tffile "examples/resources/hcp_vault_secrets_integration_aws/resource.tf" }} diff --git a/templates/resources/vault_secrets_integration_confluent.md.tmpl b/templates/resources/vault_secrets_integration_confluent.md.tmpl index e5787ca58..9aa9fcaba 100644 --- a/templates/resources/vault_secrets_integration_confluent.md.tmpl +++ b/templates/resources/vault_secrets_integration_confluent.md.tmpl @@ -9,6 +9,8 @@ description: |- {{ .Description | trimspace }} +~> **Note:** This resource is deprecated, please use `hcp_vault_secrets_integration` instead. + ## Example Usage {{ tffile "examples/resources/hcp_vault_secrets_integration_confluent/resource.tf" }} diff --git a/templates/resources/vault_secrets_integration_gcp.md.tmpl b/templates/resources/vault_secrets_integration_gcp.md.tmpl index 9857c9c59..03277f916 100644 --- a/templates/resources/vault_secrets_integration_gcp.md.tmpl +++ b/templates/resources/vault_secrets_integration_gcp.md.tmpl @@ -9,6 +9,8 @@ description: |- {{ .Description | trimspace }} +~> **Note:** This resource is deprecated, please use `hcp_vault_secrets_integration` instead. + ## Example Usage {{ tffile "examples/resources/hcp_vault_secrets_integration_gcp/resource.tf" }} diff --git a/templates/resources/vault_secrets_integration_mongodbatlas.md.tmpl b/templates/resources/vault_secrets_integration_mongodbatlas.md.tmpl index 8d3018c5d..df3a1ec1c 100644 --- a/templates/resources/vault_secrets_integration_mongodbatlas.md.tmpl +++ b/templates/resources/vault_secrets_integration_mongodbatlas.md.tmpl @@ -9,6 +9,8 @@ description: |- {{ .Description | trimspace }} +~> **Note:** This resource is deprecated, please use `hcp_vault_secrets_integration` instead. + ## Example Usage {{ tffile "examples/resources/hcp_vault_secrets_integration_mongodbatlas/resource.tf" }} diff --git a/templates/resources/vault_secrets_integration_twilio.md.tmpl b/templates/resources/vault_secrets_integration_twilio.md.tmpl index a7858de9a..5bd773f45 100644 --- a/templates/resources/vault_secrets_integration_twilio.md.tmpl +++ b/templates/resources/vault_secrets_integration_twilio.md.tmpl @@ -9,6 +9,8 @@ description: |- {{ .Description | trimspace }} +~> **Note:** This resource is deprecated, please use `hcp_vault_secrets_integration` instead. + ## Example Usage {{ tffile "examples/resources/hcp_vault_secrets_integration_twilio/resource.tf" }}