Skip to content

Commit

Permalink
[WAYP-2172] waypoint: Set variable options for add-on definition.
Browse files Browse the repository at this point in the history
  • Loading branch information
paladin-devops committed Apr 29, 2024
1 parent ab1be8f commit cf95251
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 14 deletions.
3 changes: 3 additions & 0 deletions .changelog/819.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
Support setting variable options on HCP Waypoint add-on definitions.
```
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ type DataSourceAddOnDefinitionModel struct {
Description types.String `tfsdk:"description"`
ReadmeMarkdownTemplate types.String `tfsdk:"readme_markdown_template"`

TerraformCloudWorkspace *tfcWorkspace `tfsdk:"terraform_cloud_workspace_details"`
TerraformNoCodeModule *tfcNoCodeModule `tfsdk:"terraform_no_code_module"`
TerraformCloudWorkspace *tfcWorkspace `tfsdk:"terraform_cloud_workspace_details"`
TerraformNoCodeModule *tfcNoCodeModule `tfsdk:"terraform_no_code_module"`
TerraformVariableOptions []*tfcVariableOption `tfsdk:"variable_options"`
}

func NewAddOnDefinitionDataSource() datasource.DataSource {
Expand Down Expand Up @@ -123,6 +124,27 @@ func (d *DataSourceAddOnDefinition) Schema(ctx context.Context, req datasource.S
},
},
},
"variable_options": schema.ListNestedAttribute{
Optional: true,
Description: "List of variable options for the template",
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"name": &schema.StringAttribute{
Required: true,
Description: "Variable name",
},
"variable_type": &schema.StringAttribute{
Required: true,
Description: "Variable type",
},
"options": &schema.ListAttribute{
ElementType: types.StringType,
Required: true,
Description: "List of options",
},
},
},
},
},
}
}
Expand Down Expand Up @@ -221,5 +243,27 @@ func (d *DataSourceAddOnDefinition) Read(ctx context.Context, req datasource.Rea
state.ReadmeMarkdownTemplate = types.StringNull()
}

if definition.VariableOptions != nil && len(definition.VariableOptions) > 0 {
varOpts := []*tfcVariableOption{}
for _, v := range definition.VariableOptions {
varOptsState := &tfcVariableOption{
Name: types.StringValue(v.Name),
VariableType: types.StringValue(v.VariableType),
}

vOpts, diags := types.ListValueFrom(ctx, types.StringType, v.Options)
varOptsState.Options = vOpts

resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

varOpts = append(varOpts, varOptsState)
}

state.TerraformVariableOptions = varOpts
}

resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ func TestAccWaypointData_Add_On_Definition_basic(t *testing.T) {
Config: testDataAddOnDefinitionConfig(name),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "name", name),
resource.TestCheckResourceAttr(dataSourceName, "variable_options.0.name", "string_variable"),
resource.TestCheckResourceAttr(dataSourceName, "variable_options.0.variable_type", "string"),
resource.TestCheckResourceAttr(dataSourceName, "variable_options.0.options.#", "1"),
resource.TestCheckResourceAttr(dataSourceName, "variable_options.0.options.0", "b"),
),
},
{
Expand All @@ -48,6 +52,10 @@ func TestAccWaypointData_Add_On_Definition_basic(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "name", updatedName),
resource.TestCheckResourceAttr(dataSourceName, "name", updatedName),
resource.TestCheckResourceAttr(dataSourceName, "variable_options.0.name", "string_variable"),
resource.TestCheckResourceAttr(dataSourceName, "variable_options.0.variable_type", "string"),
resource.TestCheckResourceAttr(dataSourceName, "variable_options.0.options.#", "1"),
resource.TestCheckResourceAttr(dataSourceName, "variable_options.0.options.0", "b"),
),
},
},
Expand Down
134 changes: 123 additions & 11 deletions internal/provider/waypoint/resource_waypoint_add_on_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

sharedmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-shared/v1/models"
"github.com/hashicorp/hcp-sdk-go/clients/cloud-waypoint-service/preview/2023-08-18/client/waypoint_service"
waypointmodels "github.com/hashicorp/hcp-sdk-go/clients/cloud-waypoint-service/preview/2023-08-18/models"
waypoint_models "github.com/hashicorp/hcp-sdk-go/clients/cloud-waypoint-service/preview/2023-08-18/models"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
Expand Down Expand Up @@ -46,8 +46,9 @@ type AddOnDefinitionResourceModel struct {
Description types.String `tfsdk:"description"`
ReadmeMarkdownTemplate types.String `tfsdk:"readme_markdown_template"`

TerraformCloudWorkspace *tfcWorkspace `tfsdk:"terraform_cloud_workspace_details"`
TerraformNoCodeModule *tfcNoCodeModule `tfsdk:"terraform_no_code_module"`
TerraformCloudWorkspace *tfcWorkspace `tfsdk:"terraform_cloud_workspace_details"`
TerraformNoCodeModule *tfcNoCodeModule `tfsdk:"terraform_no_code_module"`
TerraformVariableOptions []*tfcVariableOption `tfsdk:"variable_options"`
}

func (r *AddOnDefinitionResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
Expand Down Expand Up @@ -135,6 +136,27 @@ func (r *AddOnDefinitionResource) Schema(ctx context.Context, req resource.Schem
},
},
},
"variable_options": schema.ListNestedAttribute{
Optional: true,
Description: "List of variable options for the template",
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"name": &schema.StringAttribute{
Required: true,
Description: "Variable name",
},
"variable_type": &schema.StringAttribute{
Required: true,
Description: "Variable type",
},
"options": &schema.ListAttribute{
ElementType: types.StringType,
Required: true,
Description: "List of options",
},
},
},
},
},
}
}
Expand Down Expand Up @@ -209,21 +231,38 @@ func (r *AddOnDefinitionResource) Create(ctx context.Context, req resource.Creat
)
}

modelBody := &waypointmodels.HashicorpCloudWaypointWaypointServiceCreateAddOnDefinitionBody{
varOpts := []*waypoint_models.HashicorpCloudWaypointTFModuleVariable{}
for _, v := range plan.TerraformVariableOptions {
strOpts := []string{}
diags := v.Options.ElementsAs(ctx, &strOpts, false)
if diags.HasError() {
return
}

varOpts = append(varOpts, &waypoint_models.HashicorpCloudWaypointTFModuleVariable{
Name: v.Name.ValueString(),
VariableType: v.VariableType.ValueString(),
Options: strOpts,
UserEditable: false,
})
}

modelBody := &waypoint_models.HashicorpCloudWaypointWaypointServiceCreateAddOnDefinitionBody{
Name: plan.Name.ValueString(),
Summary: plan.Summary.ValueString(),
Description: plan.Description.ValueString(),
ReadmeMarkdownTemplate: readmeBytes,
Labels: stringLabels,
TerraformNocodeModule: &waypointmodels.HashicorpCloudWaypointTerraformNocodeModule{
TerraformNocodeModule: &waypoint_models.HashicorpCloudWaypointTerraformNocodeModule{
// verify these exist in the file
Source: plan.TerraformNoCodeModule.Source.ValueString(),
Version: plan.TerraformNoCodeModule.Version.ValueString(),
},
TerraformCloudWorkspaceDetails: &waypointmodels.HashicorpCloudWaypointTerraformCloudWorkspaceDetails{
TerraformCloudWorkspaceDetails: &waypoint_models.HashicorpCloudWaypointTerraformCloudWorkspaceDetails{
Name: plan.TerraformCloudWorkspace.Name.ValueString(),
ProjectID: plan.TerraformCloudWorkspace.TerraformProjectID.ValueString(),
},
VariableOptions: varOpts,
}

params := &waypoint_service.WaypointServiceCreateAddOnDefinitionParams{
Expand All @@ -236,7 +275,7 @@ func (r *AddOnDefinitionResource) Create(ctx context.Context, req resource.Creat
return
}

var addOnDefinition *waypointmodels.HashicorpCloudWaypointAddOnDefinition
var addOnDefinition *waypoint_models.HashicorpCloudWaypointAddOnDefinition
if def.Payload != nil {
addOnDefinition = def.Payload.AddOnDefinition
}
Expand Down Expand Up @@ -285,6 +324,23 @@ func (r *AddOnDefinitionResource) Create(ctx context.Context, req resource.Creat
plan.TerraformNoCodeModule = tfcNoCode
}

var actualVars []*tfcVariableOption
for _, v := range addOnDefinition.VariableOptions {
varOptsState := &tfcVariableOption{
Name: types.StringValue(v.Name),
VariableType: types.StringValue(v.VariableType),
}
varOptsState.Options, diags = types.ListValueFrom(ctx, types.StringType, v.Options)

resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

actualVars = append(actualVars, varOptsState)
}
plan.TerraformVariableOptions = actualVars

// Write logs using the tflog package
// Documentation: https://terraform.io/plugin/log
tflog.Trace(ctx, "created add-on definition resource")
Expand Down Expand Up @@ -367,6 +423,28 @@ func (r *AddOnDefinitionResource) Read(ctx context.Context, req resource.ReadReq
state.TerraformNoCodeModule = tfcNoCode
}

if definition.VariableOptions != nil && len(definition.VariableOptions) > 0 {
varOpts := []*tfcVariableOption{}
for _, v := range definition.VariableOptions {
varOptsState := &tfcVariableOption{
Name: types.StringValue(v.Name),
VariableType: types.StringValue(v.VariableType),
}

vOpts, diags := types.ListValueFrom(ctx, types.StringType, v.Options)
varOptsState.Options = vOpts

resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

varOpts = append(varOpts, varOptsState)
}

state.TerraformVariableOptions = varOpts
}

resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}

Expand Down Expand Up @@ -420,19 +498,36 @@ func (r *AddOnDefinitionResource) Update(ctx context.Context, req resource.Updat
return
}
}

varOpts := []*waypoint_models.HashicorpCloudWaypointTFModuleVariable{}
for _, v := range plan.TerraformVariableOptions {
strOpts := []string{}
diags := v.Options.ElementsAs(ctx, &strOpts, false)
if diags.HasError() {
return
}

varOpts = append(varOpts, &waypoint_models.HashicorpCloudWaypointTFModuleVariable{
Name: v.Name.ValueString(),
VariableType: v.VariableType.ValueString(),
Options: strOpts,
UserEditable: false,
})
}

// TODO: add support for Tags
modelBody := &waypointmodels.HashicorpCloudWaypointWaypointServiceUpdateAddOnDefinitionBody{
modelBody := &waypoint_models.HashicorpCloudWaypointWaypointServiceUpdateAddOnDefinitionBody{
Name: plan.Name.ValueString(),
Summary: plan.Summary.ValueString(),
Description: plan.Description.ValueString(),
ReadmeMarkdownTemplate: readmeBytes,
Labels: stringLabels,
TerraformNocodeModule: &waypointmodels.HashicorpCloudWaypointTerraformNocodeModule{
TerraformNocodeModule: &waypoint_models.HashicorpCloudWaypointTerraformNocodeModule{
// verify these exist in the file
Source: plan.TerraformNoCodeModule.Source.ValueString(),
Version: plan.TerraformNoCodeModule.Version.ValueString(),
},
TerraformCloudWorkspaceDetails: &waypointmodels.HashicorpCloudWaypointTerraformCloudWorkspaceDetails{
TerraformCloudWorkspaceDetails: &waypoint_models.HashicorpCloudWaypointTerraformCloudWorkspaceDetails{
Name: plan.TerraformCloudWorkspace.Name.ValueString(),
ProjectID: plan.TerraformCloudWorkspace.TerraformProjectID.ValueString(),
},
Expand All @@ -449,7 +544,7 @@ func (r *AddOnDefinitionResource) Update(ctx context.Context, req resource.Updat
return
}

var addOnDefinition *waypointmodels.HashicorpCloudWaypointAddOnDefinition
var addOnDefinition *waypoint_models.HashicorpCloudWaypointAddOnDefinition
if def.Payload != nil {
addOnDefinition = def.Payload.AddOnDefinition
}
Expand Down Expand Up @@ -498,6 +593,23 @@ func (r *AddOnDefinitionResource) Update(ctx context.Context, req resource.Updat
plan.TerraformNoCodeModule = tfcNoCode
}

var actualVars []*tfcVariableOption
for _, v := range addOnDefinition.VariableOptions {
varOptsState := &tfcVariableOption{
Name: types.StringValue(v.Name),
VariableType: types.StringValue(v.VariableType),
}
varOptsState.Options, diags = types.ListValueFrom(ctx, types.StringType, v.Options)

resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

actualVars = append(actualVars, varOptsState)
}
plan.TerraformVariableOptions = actualVars

// Write logs using the tflog package
// Documentation: https://terraform.io/plugin/log
tflog.Trace(ctx, "updated add-on definition resource")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ func TestAccWaypoint_Add_On_Definition_basic(t *testing.T) {
testAccCheckWaypointAddOnDefinitionExists(t, resourceName, &addOnDefinitionModel),
testAccCheckWaypointAddOnDefinitionName(t, &addOnDefinitionModel, name),
resource.TestCheckResourceAttr(resourceName, "name", name),
resource.TestCheckResourceAttr(resourceName, "variable_options.0.name", "string_variable"),
resource.TestCheckResourceAttr(resourceName, "variable_options.0.variable_type", "string"),
resource.TestCheckResourceAttr(resourceName, "variable_options.0.options.#", "1"),
resource.TestCheckResourceAttr(resourceName, "variable_options.0.options.0", "b"),
),
},
{
Expand All @@ -43,6 +47,10 @@ func TestAccWaypoint_Add_On_Definition_basic(t *testing.T) {
testAccCheckWaypointAddOnDefinitionExists(t, resourceName, &addOnDefinitionModel),
testAccCheckWaypointAddOnDefinitionName(t, &addOnDefinitionModel, updatedName),
resource.TestCheckResourceAttr(resourceName, "name", updatedName),
resource.TestCheckResourceAttr(resourceName, "variable_options.0.name", "string_variable"),
resource.TestCheckResourceAttr(resourceName, "variable_options.0.variable_type", "string"),
resource.TestCheckResourceAttr(resourceName, "variable_options.0.options.#", "1"),
resource.TestCheckResourceAttr(resourceName, "variable_options.0.options.0", "b"),
),
},
},
Expand Down Expand Up @@ -134,11 +142,20 @@ resource "hcp_waypoint_add_on_definition" "test" {
description = "some description for fun"
terraform_no_code_module = {
source = "private/waypoint-tfc-testing/waypoint-template-starter/null"
version = "0.0.2"
version = "0.0.3"
}
terraform_cloud_workspace_details = {
name = "Default Project"
terraform_project_id = "prj-gfVyPJ2q2Aurn25o"
}
variable_options = [
{
name = "string_variable"
variable_type = "string"
options = [
"b"
]
}
]
}`, name)
}

0 comments on commit cf95251

Please sign in to comment.