From f1d8d6a52bf71b57fcb0cdee51910c6ae220e1e9 Mon Sep 17 00:00:00 2001 From: "Enny J. Frick" Date: Thu, 9 Jan 2025 12:42:30 -0800 Subject: [PATCH 1/2] add allowed_account_id config parameter --- internal/provider/provider.go | 45 ++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index bb4f82b..570904c 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -2,6 +2,7 @@ package provider import ( "context" + "fmt" "os" "github.com/hashicorp/terraform-plugin-framework/datasource" @@ -10,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/provider/schema" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/types" + "go.temporal.io/api/cloud/cloudservice/v1" "github.com/temporalio/terraform-provider-temporalcloud/internal/client" ) @@ -27,9 +29,10 @@ type TerraformCloudProvider struct { // TerraformCloudProviderModel describes the provider data model. type TerraformCloudProviderModel struct { - APIKey types.String `tfsdk:"api_key"` - Endpoint types.String `tfsdk:"endpoint"` - AllowInsecure types.Bool `tfsdk:"allow_insecure"` + APIKey types.String `tfsdk:"api_key"` + Endpoint types.String `tfsdk:"endpoint"` + AllowInsecure types.Bool `tfsdk:"allow_insecure"` + AllowedAccountID types.String `tfsdk:"allowed_account_id"` } func (p *TerraformCloudProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) { @@ -69,6 +72,10 @@ in version control. We recommend passing credentials to this provider via enviro Description: "If set to True, it allows for an insecure connection to the Temporal Cloud API. This should never be set to 'true' in production and defaults to false.", Optional: true, }, + "allowed_account_id": schema.StringAttribute{ + Description: "The ID of the account to operate on. Prevents accidental mutation of accounts other than that listed", + Optional: true, + }, }, } } @@ -105,6 +112,14 @@ func (p *TerraformCloudProvider) Configure(ctx context.Context, req provider.Con " Either apply the source of the value first, or statically set the allow_insecure flag via environment variable or in configuration.") } + if data.AllowedAccountID.IsUnknown() { + resp.Diagnostics.AddAttributeError( + path.Root("allowed_account_id"), + "Unknown Terraform Cloud Allowed Account ID Value", + "The provider cannot create a Terraform Cloud API client as there is an unknown configuration value for `allowed_account_id`."+ + " Either apply the source of the value first, or statically set the Allowed Account ID value via environment variable or in configuration.") + } + apiKey := os.Getenv("TEMPORAL_CLOUD_API_KEY") if !data.APIKey.IsNull() { apiKey = data.APIKey.ValueString() @@ -123,14 +138,32 @@ func (p *TerraformCloudProvider) Configure(ctx context.Context, req provider.Con allowInsecure = data.AllowInsecure.ValueBool() } - client, err := client.NewConnectionWithAPIKey(endpoint, allowInsecure, apiKey) + allowedAccountID := os.Getenv("TEMPORAL_CLOUD_ALLOWED_ACCOUNT_ID") + if !data.AllowedAccountID.IsNull() { + allowedAccountID = data.AllowedAccountID.ValueString() + } + + cc, err := client.NewConnectionWithAPIKey(endpoint, allowInsecure, apiKey) if err != nil { resp.Diagnostics.AddError("Failed to connect to Temporal Cloud API", err.Error()) return } - resp.DataSourceData = client - resp.ResourceData = client + if allowedAccountID != "" { + accountResp, err := cc.CloudService().GetAccount(ctx, &cloudservice.GetAccountRequest{}) + if err != nil { + resp.Diagnostics.AddError("Failed to validate allowed account ID", fmt.Sprintf("failed to get account details: %s", err.Error())) + return + } + currentAccountID := accountResp.GetAccount().GetId() + if currentAccountID != allowedAccountID { + resp.Diagnostics.AddError("Failed to validate allowed account ID", fmt.Sprintf("current account ID '%s' does not match allowed account ID '%s'", currentAccountID, allowedAccountID)) + return + } + } + + resp.DataSourceData = cc + resp.ResourceData = cc } func (p *TerraformCloudProvider) Resources(ctx context.Context) []func() resource.Resource { From 917c9586fb84bff7f2ceb937520ea127bc7bcaa3 Mon Sep 17 00:00:00 2001 From: "Enny J. Frick" Date: Thu, 9 Jan 2025 12:45:34 -0800 Subject: [PATCH 2/2] docs and examples --- docs/index.md | 4 ++++ examples/provider/provider.tf | 3 +++ internal/provider/provider.go | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index 7da75dc..d7911ea 100644 --- a/docs/index.md +++ b/docs/index.md @@ -49,6 +49,9 @@ provider "temporalcloud" { # Also can be set by environment variable `TEMPORAL_CLOUD_ALLOW_INSECURE` allow_insecure = false + + # Also can be set by environment variable `TEMPORAL_CLOUD_ALLOWED_ACCOUNT_ID` + allowed_account_id = "my-temporalcloud-account-id" } ``` @@ -58,5 +61,6 @@ provider "temporalcloud" { ### Optional - `allow_insecure` (Boolean) If set to True, it allows for an insecure connection to the Temporal Cloud API. This should never be set to 'true' in production and defaults to false. +- `allowed_account_id` (String) The ID of the account to operate on. Prevents accidental mutation of accounts other than that provided. - `api_key` (String, Sensitive) The API key for Temporal Cloud. See [this documentation](https://docs.temporal.io/cloud/api-keys) for information on how to obtain an API key. - `endpoint` (String) The endpoint for the Temporal Cloud API. Defaults to `saas-api.tmprl.cloud:443`. diff --git a/examples/provider/provider.tf b/examples/provider/provider.tf index 03e498e..ab36a35 100644 --- a/examples/provider/provider.tf +++ b/examples/provider/provider.tf @@ -15,4 +15,7 @@ provider "temporalcloud" { # Also can be set by environment variable `TEMPORAL_CLOUD_ALLOW_INSECURE` allow_insecure = false + + # Also can be set by environment variable `TEMPORAL_CLOUD_ALLOWED_ACCOUNT_ID` + allowed_account_id = "my-temporalcloud-account-id" } diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 570904c..9ce8fd8 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -73,7 +73,7 @@ in version control. We recommend passing credentials to this provider via enviro Optional: true, }, "allowed_account_id": schema.StringAttribute{ - Description: "The ID of the account to operate on. Prevents accidental mutation of accounts other than that listed", + Description: "The ID of the account to operate on. Prevents accidental mutation of accounts other than that provided.", Optional: true, }, },