Skip to content

Commit

Permalink
Update Data and Resources For Boundary Controller Configs
Browse files Browse the repository at this point in the history
  • Loading branch information
RyanDerr committed Jan 8, 2025
1 parent e0cfd92 commit 8187747
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 13 deletions.
3 changes: 3 additions & 0 deletions .changelog/1164.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
Updating the provider for HCPb to allow for controller configuration settings upon hcp_boundary_cluster resource/data-source
```
10 changes: 10 additions & 0 deletions docs/data-sources/boundary_cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ If a project is not configured in the HCP Provider config block, the oldest proj
### Read-Only

- `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))
Expand All @@ -49,6 +50,15 @@ Optional:
- `default` (String)


<a id="nestedatt--controller_config"></a>
### Nested Schema for `controller_config`

Read-Only:

- `auth_token_time_to_live` (String)
- `auth_token_time_to_stale` (String)


<a id="nestedatt--maintenance_window_config"></a>
### Nested Schema for `maintenance_window_config`

Expand Down
10 changes: 10 additions & 0 deletions docs/resources/boundary_cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ 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))
- `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.
Expand All @@ -51,6 +52,15 @@ 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.

<a id="nestedblock--controller_config"></a>
### 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.


<a id="nestedblock--maintenance_window_config"></a>
### Nested Schema for `maintenance_window_config`

Expand Down
29 changes: 26 additions & 3 deletions internal/clients/boundary_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func GetBoundaryClusterControllerConfigByID(
client *Client,
loc *sharedmodels.HashicorpCloudLocationLocation,
boundaryClusterID string,
) (*boundarymodels.HashicorpCloudBoundary20211221GetControllerConfigurationResponse, error) {
) (*boundarymodels.HashicorpCloudBoundary20211221ControllerConfiguration, error) {

params := boundary_service.NewBoundaryServiceGetControllerConfigurationParams()
params.Context = ctx
Expand All @@ -134,7 +134,7 @@ func GetBoundaryClusterControllerConfigByID(
return nil, err
}

return resp.Payload, nil
return resp.Payload.Config, nil
}

// UpdateBoundaryClusterControllerConfig updates the controllers auth config for TTL and TTS on a Boundary cluster.
Expand All @@ -160,4 +160,27 @@ func UpdateBoundaryClusterControllerConfig(
}

return nil
}
}

// ResetBoundaryClusterControllerConfig resets the controllers auth config for TTL and TTS on a Boundary cluster.
func ResetBoundaryClusterControllerConfig(
ctx context.Context,
client *Client,
loc *sharedmodels.HashicorpCloudLocationLocation,
boundaryClusterID string,
) error {

params := boundary_service.NewBoundaryServiceResetControllerConfigurationParams()
params.Context = ctx

params.LocationOrganizationID = loc.OrganizationID
params.LocationProjectID = loc.ProjectID
params.ClusterID = boundaryClusterID

_, err := client.Boundary.BoundaryServiceResetControllerConfiguration(params, nil)
if err != nil {
return err
}

return nil
}
25 changes: 24 additions & 1 deletion internal/providersdkv2/data_source_boundary_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,24 @@ 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,
},
},
},
},
},
}
}
Expand Down Expand Up @@ -135,8 +153,13 @@ func dataSourceBoundaryClusterRead(ctx context.Context, d *schema.ResourceData,
return diag.Errorf("unable to fetch maintenenace window Boundary cluster (%s): %v", clusterID, err)
}

controllerConfig, err := clients.GetBoundaryClusterControllerConfigByID(ctx, client, loc, clusterID)
if err != nil {
return diag.Errorf("unable to fetch controller config for Boundary cluster (%s): %v", clusterID, err)
}

// cluster found, update resource data
if err := setBoundaryClusterResourceData(d, cluster, clusterUpgradeType, clusterMW); err != nil {
if err := setBoundaryClusterResourceData(d, cluster, clusterUpgradeType, clusterMW, controllerConfig); err != nil {
return diag.FromErr(err)
}

Expand Down
164 changes: 155 additions & 9 deletions internal/providersdkv2/resource_boundary_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,53 @@ 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
},
},
},
},
},
},
}
}
Expand Down Expand Up @@ -205,6 +252,12 @@ func resourceBoundaryClusterCreate(ctx context.Context, d *schema.ResourceData,
return diagErr
}

controllerConfig, diagErr := getBoundaryClusterControllerConfig(d)

if diagErr != nil {
return diagErr
}

// check for an existing boundary cluster
_, err = clients.GetBoundaryClusterByID(ctx, client, loc, clusterID)
if err != nil {
Expand All @@ -219,11 +272,12 @@ func resourceBoundaryClusterCreate(ctx context.Context, d *schema.ResourceData,

// assemble the BoundaryClusterCreateRequest
req := &boundarymodels.HashicorpCloudBoundary20211221CreateRequest{
ClusterID: clusterID,
Username: username,
Password: password,
Location: loc,
MarketingSku: &tierPb,
ClusterID: clusterID,
Username: username,
Password: password,
Location: loc,
MarketingSku: &tierPb,
ControllerConfig: controllerConfig,
}

// execute the Boundary cluster creation
Expand Down Expand Up @@ -271,8 +325,14 @@ 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)
err = setBoundaryClusterResourceData(d, cluster, currentUpgradeType, currentMaintenanceWindow, currentControllerConfig)
if err != nil {
return diag.FromErr(err)
}
Expand All @@ -296,6 +356,11 @@ func resourceBoundaryClusterUpdate(ctx context.Context, d *schema.ResourceData,
return diagErr
}

controllerConfig, dialErr := getBoundaryClusterControllerConfig(d)
if dialErr != nil {
return dialErr
}

log.Printf("[INFO] Reading Boundary cluster (%s) [project_id=%s, organization_id=%s]", clusterID, loc.ProjectID, loc.OrganizationID)

cluster, err := clients.GetBoundaryClusterByID(ctx, client, loc, clusterID)
Expand Down Expand Up @@ -331,8 +396,28 @@ func resourceBoundaryClusterUpdate(ctx context.Context, d *schema.ResourceData,
currentUpgradeType = upgradeType
}

log.Printf("[INFO] Updated controller configuration for Boundary cluster (%s) [project_id=%s, organization_id=%s]", clusterID, loc.ProjectID, loc.OrganizationID)

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)
}

// update the controller configuration if it was created
if controllerConfig != nil {
ctrlConfigReq := boundarymodels.HashicorpCloudBoundary20211221UpdateControllerConfigurationRequest{}
ctrlConfigReq.ClusterID = cluster.ClusterID
ctrlConfigReq.Location = cluster.Location
ctrlConfigReq.Config = controllerConfig

if err = clients.UpdateBoundaryClusterControllerConfig(ctx, client, loc, clusterID, &ctrlConfigReq); err != nil {
return diag.Errorf("error updating controller configuration for Boundary cluster (%s): %v", clusterID, err)
}
currentControllerConfig = controllerConfig
}

// set Boundary cluster resource data
err = setBoundaryClusterResourceData(d, cluster, currentUpgradeType, currentMaintenanceWindow)
err = setBoundaryClusterResourceData(d, cluster, currentUpgradeType, currentMaintenanceWindow, currentControllerConfig)
if err != nil {
return diag.FromErr(err)
}
Expand Down Expand Up @@ -376,8 +461,13 @@ func resourceBoundaryClusterRead(ctx context.Context, d *schema.ResourceData, me
return diag.Errorf("unable to fetch maintenenace window Boundary cluster (%s): %v", clusterID, err)
}

controllerConfig, 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)
}

// Cluster found, update resource data.
if err := setBoundaryClusterResourceData(d, cluster, clusterUpgradeType, clusterMW); err != nil {
if err := setBoundaryClusterResourceData(d, cluster, clusterUpgradeType, clusterMW, controllerConfig); err != nil {
return diag.FromErr(err)
}

Expand Down Expand Up @@ -455,7 +545,7 @@ func resourceBoundaryClusterImport(ctx context.Context, d *schema.ResourceData,
return []*schema.ResourceData{d}, nil
}

func setBoundaryClusterResourceData(d *schema.ResourceData, cluster *boundarymodels.HashicorpCloudBoundary20211221Cluster, upgradeType *boundarymodels.HashicorpCloudBoundary20211221UpgradeType, clusterMW *boundarymodels.HashicorpCloudBoundary20211221MaintenanceWindow) error {
func setBoundaryClusterResourceData(d *schema.ResourceData, cluster *boundarymodels.HashicorpCloudBoundary20211221Cluster, upgradeType *boundarymodels.HashicorpCloudBoundary20211221UpgradeType, clusterMW *boundarymodels.HashicorpCloudBoundary20211221MaintenanceWindow, clusterCtrlConfig *boundarymodels.HashicorpCloudBoundary20211221ControllerConfiguration) error {
if err := d.Set("cluster_id", cluster.ClusterID); err != nil {
return err
}
Expand Down Expand Up @@ -496,6 +586,24 @@ 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()
}

if err := d.Set("controller_config", []any{ctrlConfig}); err != nil {
return err
}

if err := d.Set("version", cluster.BoundaryVersion); err != nil {
return err
}
Expand Down Expand Up @@ -561,3 +669,41 @@ func getBoundaryClusterMaintainanceWindowConfig(d *schema.ResourceData) (*bounda

return &upgradeType, maintenanceWindow, nil
}

func getBoundaryClusterControllerConfig(d *schema.ResourceData) (*boundarymodels.HashicorpCloudBoundary20211221ControllerConfiguration, diag.Diagnostics) {
if !d.HasChange("controller_config") {
return nil, nil
}

// get the controller_config resources
controllerConfigParam, ok := d.GetOk("controller_config")
if !ok {
return nil, nil
}

// convert to []any is required even though we set a MaxItems=1
controllerConfigs, ok := controllerConfigParam.([]any)
if !ok || len(controllerConfigs) == 0 {
return nil, nil
}

// get the elements in the config
controllerConfigElems, ok := controllerConfigs[0].(map[string]any)
if !ok || len(controllerConfigElems) == 0 {
return nil, nil
}

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()

if authTTL < authTTS {
return nil, diag.Errorf("controller configuration is invalid: `auth_token_time_to_live` should be greater than or equal to `auth_token_time_to_stale`")
}

return controllerConfig, nil
}

0 comments on commit 8187747

Please sign in to comment.