diff --git a/GNUmakefile b/GNUmakefile index c96f79c85..c4d86a554 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -41,7 +41,7 @@ test-ci: fmtcheck go test -coverprofile=coverage.out ./... go tool cover -html=coverage.out -o coverage.html -testacc: fmtcheck +testacc: @if [ "$(TESTARGS)" = "-run=TestAccXXX" ]; then \ echo ""; \ echo "Error: Skipping example acceptance testing pattern. Update TESTARGS to match the test naming in the relevant *_test.go file."; \ diff --git a/docs/data-sources/boundary_cluster.md b/docs/data-sources/boundary_cluster.md index 4ae9a6b08..b57fad330 100644 --- a/docs/data-sources/boundary_cluster.md +++ b/docs/data-sources/boundary_cluster.md @@ -33,8 +33,9 @@ If a project is not configured in the HCP Provider config block, the oldest proj ### Read-Only +- `auth_token_time_to_live` (String) The time to live for the auth token in golang's time.Duration string format. +- `auth_token_time_to_stale` (String) The time to stale for the auth token in golang's time.Duration string format. - `cluster_url` (String) A unique URL identifying the Boundary cluster. -- `controller_config` (List of Object) (see [below for nested schema](#nestedatt--controller_config)) - `created_at` (String) The time that the Boundary cluster was created. - `id` (String) The ID of this resource. - `maintenance_window_config` (List of Object) (see [below for nested schema](#nestedatt--maintenance_window_config)) @@ -50,15 +51,6 @@ Optional: - `default` (String) - -### Nested Schema for `controller_config` - -Read-Only: - -- `auth_token_time_to_live` (String) -- `auth_token_time_to_stale` (String) - - ### Nested Schema for `maintenance_window_config` diff --git a/docs/resources/boundary_cluster.md b/docs/resources/boundary_cluster.md index d2d6c584a..637bebb9b 100644 --- a/docs/resources/boundary_cluster.md +++ b/docs/resources/boundary_cluster.md @@ -22,10 +22,8 @@ resource "hcp_boundary_cluster" "example" { end = 12 upgrade_type = "SCHEDULED" } - controller_config { - auth_token_time_to_live = "36h0m0s" - auth_token_time_to_stale = "12h0m0s" - } + auth_token_time_to_live = "36h0m0s" + auth_token_time_to_stale = "12h0m0s" } ``` @@ -41,7 +39,8 @@ resource "hcp_boundary_cluster" "example" { ### Optional -- `controller_config` (Block List, Max: 1) The controller configuration for the Boundary cluster. (see [below for nested schema](#nestedblock--controller_config)) +- `auth_token_time_to_live` (String) The time to live for the auth token in golang's time.Duration string format. +- `auth_token_time_to_stale` (String) The time to stale for the auth token in golang's time.Duration string format. - `maintenance_window_config` (Block List, Max: 1) The maintenance window configuration for when cluster upgrades can take place. (see [below for nested schema](#nestedblock--maintenance_window_config)) - `project_id` (String) The ID of the HCP project where the Boundary cluster is located. If not specified, the project specified in the HCP Provider config block will be used, if configured. @@ -56,15 +55,6 @@ If a project is not configured in the HCP Provider config block, the oldest proj - `state` (String) The state of the Boundary cluster. - `version` (String) The version of the Boundary cluster. - -### Nested Schema for `controller_config` - -Optional: - -- `auth_token_time_to_live` (String) The time to live for the auth token in the format of golang's time.Duration string. -- `auth_token_time_to_stale` (String) The time to stale for the auth token in the format of golang's time.Duration string. - - ### Nested Schema for `maintenance_window_config` diff --git a/examples/resources/hcp_boundary_cluster/resource.tf b/examples/resources/hcp_boundary_cluster/resource.tf index bafd392ad..f2a1b8dfc 100644 --- a/examples/resources/hcp_boundary_cluster/resource.tf +++ b/examples/resources/hcp_boundary_cluster/resource.tf @@ -8,8 +8,6 @@ resource "hcp_boundary_cluster" "example" { end = 12 upgrade_type = "SCHEDULED" } - controller_config { - auth_token_time_to_live = "36h0m0s" - auth_token_time_to_stale = "12h0m0s" - } + auth_token_time_to_live = "36h0m0s" + auth_token_time_to_stale = "12h0m0s" } diff --git a/internal/providersdkv2/data_source_boundary_cluster.go b/internal/providersdkv2/data_source_boundary_cluster.go index 54344428c..89ee5193b 100644 --- a/internal/providersdkv2/data_source_boundary_cluster.go +++ b/internal/providersdkv2/data_source_boundary_cluster.go @@ -94,23 +94,15 @@ If a project is not configured in the HCP Provider config block, the oldest proj Type: schema.TypeString, Computed: true, }, - "controller_config": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "auth_token_time_to_live": { - Description: "The time to live for the auth token in time.Duration format.", - Type: schema.TypeString, - Computed: true, - }, - "auth_token_time_to_stale": { - Description: "The time to stale for the auth token in time.Duration format.", - Type: schema.TypeString, - Computed: true, - }, - }, - }, + "auth_token_time_to_live": { + Description: "The time to live for the auth token in golang's time.Duration string format.", + Type: schema.TypeString, + Computed: true, + }, + "auth_token_time_to_stale": { + Description: "The time to stale for the auth token in golang's time.Duration string format.", + Type: schema.TypeString, + Computed: true, }, }, } diff --git a/internal/providersdkv2/resource_boundary_cluster.go b/internal/providersdkv2/resource_boundary_cluster.go index 35941e442..a825b6aec 100644 --- a/internal/providersdkv2/resource_boundary_cluster.go +++ b/internal/providersdkv2/resource_boundary_cluster.go @@ -166,51 +166,42 @@ If a project is not configured in the HCP Provider config block, the oldest proj Type: schema.TypeString, Computed: true, }, - "controller_config": { - Description: "The controller configuration for the Boundary cluster.", - Type: schema.TypeList, - Optional: true, - Computed: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "auth_token_time_to_live": { - Description: "The time to live for the auth token in the format of golang's time.Duration string.", - Type: schema.TypeString, - Optional: true, - ValidateFunc: func(i any, k string) (warnings []string, errors []error) { - _, err := time.ParseDuration(i.(string)) - if err != nil { - errors = append(errors, fmt.Errorf("expected %s to be a valid duration, got %s", k, i)) - } - return warnings, errors - }, - RequiredWith: []string{"controller_config.0.auth_token_time_to_stale"}, - DiffSuppressFunc: func(_, old, new string, _ *schema.ResourceData) bool { - oldTime, _ := time.ParseDuration(old) - newTime, _ := time.ParseDuration(new) - return newTime == oldTime - }, - }, - "auth_token_time_to_stale": { - Description: "The time to stale for the auth token in the format of golang's time.Duration string.", - Type: schema.TypeString, - Optional: true, - ValidateFunc: func(i any, k string) (warnings []string, errors []error) { - _, err := time.ParseDuration(i.(string)) - if err != nil { - errors = append(errors, fmt.Errorf("expected %s to be a valid duration, got %s", k, i)) - } - return warnings, errors - }, - RequiredWith: []string{"controller_config.0.auth_token_time_to_live"}, - DiffSuppressFunc: func(_, old, new string, _ *schema.ResourceData) bool { - oldTime, _ := time.ParseDuration(old) - newTime, _ := time.ParseDuration(new) - return newTime == oldTime - }, - }, - }, + "auth_token_time_to_live": { + Description: "The time to live for the auth token in golang's time.Duration string format.", + Type: schema.TypeString, + Optional: true, + Default: "1680h0m0s", + RequiredWith: []string{"auth_token_time_to_stale"}, + ValidateFunc: func(i any, k string) (warnings []string, errors []error) { + _, err := time.ParseDuration(i.(string)) + if err != nil { + errors = append(errors, fmt.Errorf("expected %s to be a valid duration, got %s", k, i)) + } + return warnings, errors + }, + DiffSuppressFunc: func(_, old, new string, _ *schema.ResourceData) bool { + oldTime, _ := time.ParseDuration(old) + newTime, _ := time.ParseDuration(new) + return newTime == oldTime + }, + }, + "auth_token_time_to_stale": { + Description: "The time to stale for the auth token in golang's time.Duration string format.", + Type: schema.TypeString, + Optional: true, + Default: "24h0m0s", + RequiredWith: []string{"auth_token_time_to_live"}, + ValidateFunc: func(i any, k string) (warnings []string, errors []error) { + _, err := time.ParseDuration(i.(string)) + if err != nil { + errors = append(errors, fmt.Errorf("expected %s to be a valid duration, got %s", k, i)) + } + return warnings, errors + }, + DiffSuppressFunc: func(_, old, new string, _ *schema.ResourceData) bool { + oldTime, _ := time.ParseDuration(old) + newTime, _ := time.ParseDuration(new) + return newTime == oldTime }, }, }, @@ -325,14 +316,8 @@ func resourceBoundaryClusterCreate(ctx context.Context, d *schema.ResourceData, currentUpgradeType = upgradeType } - // Retrieve the controller configuration in the case it was not provided - currentControllerConfig, err := clients.GetBoundaryClusterControllerConfigByID(ctx, client, loc, clusterID) - if err != nil { - return diag.Errorf("unable to fetch controller configuration for Boundary cluster (%s): %v", clusterID, err) - } - // set Boundary cluster resource data - err = setBoundaryClusterResourceData(d, cluster, currentUpgradeType, currentMaintenanceWindow, currentControllerConfig) + err = setBoundaryClusterResourceData(d, cluster, currentUpgradeType, currentMaintenanceWindow, controllerConfig) if err != nil { return diag.FromErr(err) } @@ -586,21 +571,21 @@ func setBoundaryClusterResourceData(d *schema.ResourceData, cluster *boundarymod return err } - ctrlConfig := map[string]any{} - if clusterCtrlConfig != nil { - authTTL, err := time.ParseDuration(clusterCtrlConfig.AuthTokenTimeToLive) - if err != nil { - return fmt.Errorf("unable to parse auth_token_time_to_live to time: %v", err) - } - authTTS, err := time.ParseDuration(clusterCtrlConfig.AuthTokenTimeToStale) - if err != nil { - return fmt.Errorf("unable to parse auth_token_time_to_stale to time: %v", err) - } - ctrlConfig["auth_token_time_to_live"] = authTTL.String() - ctrlConfig["auth_token_time_to_stale"] = authTTS.String() + authTTL, err := time.ParseDuration(clusterCtrlConfig.AuthTokenTimeToLive) + if err != nil { + return fmt.Errorf("unable to parse auth_token_time_to_live to time: %v", err) + } + + authTTS, err := time.ParseDuration(clusterCtrlConfig.AuthTokenTimeToStale) + if err != nil { + return fmt.Errorf("unable to parse auth_token_time_to_stale to time: %v", err) + } + + if err := d.Set("auth_token_time_to_live", authTTL.String()); err != nil { + return err } - if err := d.Set("controller_config", []any{ctrlConfig}); err != nil { + if err := d.Set("auth_token_time_to_stale", authTTS.String()); err != nil { return err } @@ -671,33 +656,21 @@ func getBoundaryClusterMaintainanceWindowConfig(d *schema.ResourceData) (*bounda } func getBoundaryClusterControllerConfig(d *schema.ResourceData) (*boundarymodels.HashicorpCloudBoundary20211221ControllerConfiguration, diag.Diagnostics) { - if !d.HasChange("controller_config") { + if !d.HasChange("auth_token_time_to_live") && !d.HasChange("auth_token_time_to_stale") { return nil, nil } - // get the controller_config resources - controllerConfigParam, ok := d.GetOk("controller_config") - if !ok { - return nil, nil - } + controllerConfig := &boundarymodels.HashicorpCloudBoundary20211221ControllerConfiguration{} - // convert to []any is required even though we set a MaxItems=1 - controllerConfigs, ok := controllerConfigParam.([]any) - if !ok || len(controllerConfigs) == 0 { - return nil, nil + authTTL, err := time.ParseDuration(d.Get("auth_token_time_to_live").(string)) + if err != nil { + return nil, diag.Errorf("unable to parse auth_token_time_to_live to time: %v", err) } - - // get the elements in the config - controllerConfigElems, ok := controllerConfigs[0].(map[string]any) - if !ok || len(controllerConfigElems) == 0 { - return nil, nil + authTTS, err := time.ParseDuration(d.Get("auth_token_time_to_stale").(string)) + if err != nil { + return nil, diag.Errorf("unable to parse auth_token_time_to_stale to time: %v", err) } - controllerConfig := &boundarymodels.HashicorpCloudBoundary20211221ControllerConfiguration{} - - authTTL, _ := time.ParseDuration(controllerConfigElems["auth_token_time_to_live"].(string)) - authTTS, _ := time.ParseDuration(controllerConfigElems["auth_token_time_to_stale"].(string)) - controllerConfig.AuthTokenTimeToLive = authTTL.String() controllerConfig.AuthTokenTimeToStale = authTTS.String() diff --git a/internal/providersdkv2/resource_boundary_cluster_test.go b/internal/providersdkv2/resource_boundary_cluster_test.go index 88f95e756..a7cfa9120 100644 --- a/internal/providersdkv2/resource_boundary_cluster_test.go +++ b/internal/providersdkv2/resource_boundary_cluster_test.go @@ -35,8 +35,14 @@ var maintenanceWindowConfig = ` } ` +var controllerConfig = ` + auth_token_time_to_live = "12h0m0s" + auth_token_time_to_stale = "1h0m0s" +` + var boundaryCluster = fmt.Sprintf(boundaryClusterResourceTemplate, "") var boundaryClusterWithMaintenanceWindow = fmt.Sprintf(boundaryClusterResourceTemplate, maintenanceWindowConfig) +var boundaryClusterWithControllerConfig = fmt.Sprintf(boundaryClusterResourceTemplate, controllerConfig) func setTestAccBoundaryClusterConfig(boundaryCluster string) string { return fmt.Sprintf(` @@ -69,6 +75,8 @@ func TestAccBoundaryCluster(t *testing.T) { resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "state"), resource.TestCheckResourceAttr(boundaryClusterResourceName, "tier", "PLUS"), resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "version"), + resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "auth_token_time_to_live"), + resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "auth_token_time_to_stale"), ), }, { @@ -98,6 +106,8 @@ func TestAccBoundaryCluster(t *testing.T) { resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "state"), resource.TestCheckResourceAttr(boundaryClusterResourceName, "tier", "PLUS"), resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "version"), + resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "auth_token_time_to_live"), + resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "auth_token_time_to_stale"), ), }, { @@ -111,6 +121,8 @@ func TestAccBoundaryCluster(t *testing.T) { resource.TestCheckResourceAttrPair(boundaryClusterResourceName, "state", boundaryClusterDataSourceName, "state"), resource.TestCheckResourceAttr(boundaryClusterResourceName, "tier", "PLUS"), resource.TestCheckResourceAttrPair(boundaryClusterResourceName, "version", boundaryClusterDataSourceName, "version"), + resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "auth_token_time_to_live"), + resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "auth_token_time_to_stale"), ), }, { @@ -129,6 +141,24 @@ func TestAccBoundaryCluster(t *testing.T) { resource.TestCheckResourceAttr(boundaryClusterResourceName, "maintenance_window_config.0.start", "2"), resource.TestCheckResourceAttr(boundaryClusterResourceName, "maintenance_window_config.0.end", "12"), resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "version"), + resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "auth_token_time_to_live"), + resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "auth_token_time_to_stale"), + ), + }, + { + // this test step tests creating a boundary cluster with non-default controller config settings. + Config: testConfig(setTestAccBoundaryClusterConfig(boundaryClusterWithControllerConfig)), + Check: resource.ComposeTestCheckFunc( + testAccCheckBoundaryClusterExists(boundaryClusterResourceName), + resource.TestCheckResourceAttr(boundaryClusterResourceName, "cluster_id", boundaryUniqueID), + resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "created_at"), + resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "cluster_url"), + testAccCheckFullURL(boundaryClusterResourceName, "cluster_url", ""), + resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "state"), + resource.TestCheckResourceAttr(boundaryClusterResourceName, "tier", "PLUS"), + resource.TestCheckResourceAttrSet(boundaryClusterResourceName, "version"), + resource.TestCheckResourceAttr(boundaryClusterResourceName, "auth_token_time_to_live", "12h0m0s"), + resource.TestCheckResourceAttr(boundaryClusterResourceName, "auth_token_time_to_stale", "1h0m0s"), ), }, },