diff --git a/internal/provider/apikey_resource.go b/internal/provider/apikey_resource.go index 42dda79..6e3b965 100644 --- a/internal/provider/apikey_resource.go +++ b/internal/provider/apikey_resource.go @@ -7,6 +7,7 @@ import ( "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/boolplanmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" @@ -30,6 +31,7 @@ type ( DisplayName types.String `tfsdk:"display_name"` Description types.String `tfsdk:"description"` ExpiryTime types.String `tfsdk:"expiry_time"` // ISO 8601 format + Disabled types.Bool `tfsdk:"disabled"` Timeouts timeouts.Value `tfsdk:"timeouts"` } ) @@ -119,6 +121,13 @@ func (r *apiKeyResource) Schema(ctx context.Context, _ resource.SchemaRequest, r stringplanmodifier.RequiresReplace(), }, }, + "disabled": schema.BoolAttribute{ + Description: "Whether the API key is disabled.", + Optional: true, + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.RequiresReplace(), + }, + }, }, Blocks: map[string]schema.Block{ "timeouts": timeouts.Block(ctx, timeouts.Opts{ @@ -161,6 +170,11 @@ func (r *apiKeyResource) Create(ctx context.Context, req resource.CreateRequest, description = plan.Description.ValueString() } + disabled := false + if !plan.Disabled.IsNull() { + disabled = plan.Disabled.ValueBool() + } + svcResp, err := r.client.CloudService().CreateApiKey(ctx, &cloudservicev1.CreateApiKeyRequest{ Spec: &identityv1.ApiKeySpec{ OwnerId: plan.OwnerID.ValueString(), @@ -168,6 +182,7 @@ func (r *apiKeyResource) Create(ctx context.Context, req resource.CreateRequest, DisplayName: plan.DisplayName.ValueString(), Description: description, ExpiryTime: expiryTimestamp, + Disabled: disabled, }, }) @@ -237,14 +252,25 @@ func (r *apiKeyResource) Update(ctx context.Context, req resource.UpdateRequest, // Convert time.Time to protobuf Timestamp expiryTimestamp := timestamppb.New(expiryTime) + description := "" + if !plan.Description.IsNull() { + description = plan.Description.ValueString() + } + + disabled := false + if !plan.Disabled.IsNull() { + disabled = plan.Disabled.ValueBool() + } + svcResp, err := r.client.CloudService().UpdateApiKey(ctx, &cloudservicev1.UpdateApiKeyRequest{ KeyId: plan.ID.ValueString(), Spec: &identityv1.ApiKeySpec{ OwnerId: plan.OwnerID.ValueString(), OwnerType: plan.OwnerType.ValueString(), DisplayName: plan.DisplayName.ValueString(), - Description: plan.Description.ValueString(), + Description: description, ExpiryTime: expiryTimestamp, + Disabled: disabled, }, ResourceVersion: apiKey.GetApiKey().GetResourceVersion(), }) @@ -322,4 +348,7 @@ func updateApiKeyModelFromSpec(state *apiKeyResourceModel, apikey *identityv1.Ap state.Description = types.StringValue(apikey.GetSpec().GetDescription()) } state.ExpiryTime = types.StringValue(apikey.GetSpec().GetExpiryTime().AsTime().Format(time.RFC3339)) + //if apikey.GetSpec().GetDisabled() != false { + // state.Disabled = types.BoolValue(apikey.GetSpec().GetDisabled()) + //} } diff --git a/internal/provider/apikey_resource_test.go b/internal/provider/apikey_resource_test.go index d0535e0..2390380 100644 --- a/internal/provider/apikey_resource_test.go +++ b/internal/provider/apikey_resource_test.go @@ -1,15 +1,24 @@ package provider import ( + "context" + "errors" "fmt" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + cloudservicev1 "go.temporal.io/api/cloud/cloudservice/v1" "testing" + "time" ) func createRandomApiKeyName() string { return fmt.Sprintf("key-terraformprovider-%s", randomString()) } +func getExpiryTime() string { + return time.Now().Add(30 * 24 * time.Hour).UTC().Format(time.RFC3339) +} + func TestAccBasicApiKey(t *testing.T) { apiKeyName := createRandomApiKeyName() description := "TEST API Key" @@ -20,17 +29,18 @@ provider "temporalcloud" { } resource "temporalcloud_apikey" "terraform" { - display_name = "%s" - owner_type = "%s" - owner_id = "%s" - expiry_time = "2024-10-01T00:00:00Z"`, displayName, ownerType, ownerId) + display_name = "%s" + owner_type = "%s" + owner_id = "%s" + expiry_time = "%s"`, displayName, ownerType, ownerId, getExpiryTime()) if description != nil { tmpConfig += fmt.Sprintf(` description = "%s"`, *description) } - tmpConfig += `}` + tmpConfig += ` +}` return tmpConfig } @@ -42,6 +52,34 @@ resource "temporalcloud_apikey" "terraform" { Steps: []resource.TestStep{ { Config: config(apiKeyName, "service-account", "d6d0d3ff3f8c400e82ffe58d15d79fa5", nil), + Check: func(s *terraform.State) error { + id := s.RootModule().Resources["temporalcloud_apikey.terraform"].Primary.Attributes["id"] + conn := newConnection(t) + apiKey, err := conn.GetApiKey(context.Background(), &cloudservicev1.GetApiKeyRequest{ + KeyId: id, + }) + if err != nil { + return fmt.Errorf("failed to get namespace: %v", err) + } + + spec := apiKey.ApiKey.GetSpec() + if spec.GetDisabled() { + return errors.New("expected disabled to be false") + } + if spec.GetDisplayName() != apiKeyName { + return fmt.Errorf("expected display name to be %s, got %s", apiKeyName, spec.GetDisplayName()) + } + if spec.GetOwnerType() != "service-account" { + return fmt.Errorf("expected owner type to be service-account, got %s", spec.GetOwnerType()) + } + if spec.GetOwnerId() != "d6d0d3ff3f8c400e82ffe58d15d79fa5" { + return fmt.Errorf("expected owner id to be d6d0d3ff3f8c400e82ffe58d15d79fa5, got %s", spec.GetOwnerId()) + } + return nil + }, + }, + { + Config: config(apiKeyName, "service-account", "d6d0d3ff3f8c400e82ffe58d15d79fa5", &description), }, { Config: config(apiKeyName, "service-account", "d6d0d3ff3f8c400e82ffe58d15d79fa5", &description), @@ -49,3 +87,100 @@ resource "temporalcloud_apikey" "terraform" { }, }) } + +func TestAccDisableApiKey(t *testing.T) { + apiKeyName := createRandomApiKeyName() + config := func(displayName string, ownerType string, ownerId string, disable bool) string { + tmpConfig := fmt.Sprintf(` +provider "temporalcloud" { + +} + +resource "temporalcloud_apikey" "test" { + display_name = "%s" + owner_type = "%s" + owner_id = "%s" + expiry_time = "%s"`, displayName, ownerType, ownerId, getExpiryTime()) + + if !disable { + tmpConfig += fmt.Sprintf(` + disabled = false`) + } else { + tmpConfig += fmt.Sprintf(` + disabled = true`) + } + + tmpConfig += ` +}` + return tmpConfig + } + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + // do nothing + Config: config(apiKeyName, "service-account", "d6d0d3ff3f8c400e82ffe58d15d79fa5", false), + Check: func(s *terraform.State) error { + id := s.RootModule().Resources["temporalcloud_apikey.test"].Primary.Attributes["id"] + conn := newConnection(t) + apiKey, err := conn.GetApiKey(context.Background(), &cloudservicev1.GetApiKeyRequest{ + KeyId: id, + }) + if err != nil { + return fmt.Errorf("failed to get namespace: %v", err) + } + + spec := apiKey.ApiKey.GetSpec() + if spec.GetDisabled() { + return errors.New("expected disabled to be false") + } + return nil + }, + }, + { + // disable + Config: config(apiKeyName, "service-account", "d6d0d3ff3f8c400e82ffe58d15d79fa5", true), + Check: func(s *terraform.State) error { + id := s.RootModule().Resources["temporalcloud_apikey.test"].Primary.Attributes["id"] + conn := newConnection(t) + apiKey, err := conn.GetApiKey(context.Background(), &cloudservicev1.GetApiKeyRequest{ + KeyId: id, + }) + if err != nil { + return fmt.Errorf("failed to get namespace: %v", err) + } + + spec := apiKey.ApiKey.GetSpec() + if !spec.GetDisabled() { + return errors.New("expected disabled to be true") + } + return nil + }, + }, + { + // enable back again + Config: config(apiKeyName, "service-account", "d6d0d3ff3f8c400e82ffe58d15d79fa5", false), + Check: func(s *terraform.State) error { + id := s.RootModule().Resources["temporalcloud_apikey.test"].Primary.Attributes["id"] + conn := newConnection(t) + apiKey, err := conn.GetApiKey(context.Background(), &cloudservicev1.GetApiKeyRequest{ + KeyId: id, + }) + if err != nil { + return fmt.Errorf("failed to get namespace: %v", err) + } + + spec := apiKey.ApiKey.GetSpec() + if spec.GetDisabled() { + return errors.New("expected disabled to be false") + } + return nil + }, + }, + }, + }) +}