Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/1224.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
Add way to assign actions to a Waypoint template or application on create or update.
```
1 change: 1 addition & 0 deletions docs/data-sources/waypoint_application.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The Waypoint Application data source retrieves information on a given Applicatio

### Optional

- `actions` (List of String) List of actions by 'ID' to assign to this Template. Applications created from this Template will have these actions assigned to them. Only 'ID' is supported.
- `id` (String) The ID of the Application.
- `input_variables` (Attributes Set) Input variables for the Application. (see [below for nested schema](#nestedatt--input_variables))
- `name` (String) The name of the Application.
Expand Down
1 change: 1 addition & 0 deletions docs/data-sources/waypoint_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ data "hcp_waypoint_template" "example" {

### Optional

- `actions` (List of String) List of actions by 'ID' to assign to this Template. Applications created from this Template will have these actions assigned to them. Only 'ID' is supported.
- `id` (String) The ID of the Template.
- `name` (String) The name of the Template.
- `project_id` (String) The ID of the HCP project where the Waypoint Template is located.
Expand Down
1 change: 1 addition & 0 deletions docs/resources/waypoint_application.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ The Waypoint Application resource managed the lifecycle of an Application that's

### Optional

- `actions` (List of String) List of actions by 'ID' to assign to this Template. Applications created from this Template will have these actions assigned to them. Only 'ID' is supported.
- `application_input_variables` (Attributes Set) Input variables set for the application. (see [below for nested schema](#nestedatt--application_input_variables))
- `project_id` (String) The ID of the HCP project where the Waypoint Application is located.
- `readme_markdown` (String) Instructions for using the Application (markdown format supported). Note: this is a base64 encoded string, and can only be set in configuration after initial creation. The initial version of the README is generated from the README Template from source Template.
Expand Down
1 change: 1 addition & 0 deletions docs/resources/waypoint_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ EOF

### Optional

- `actions` (List of String) List of actions by 'ID' to assign to this Template. Applications created from this Template will have these actions assigned to them. Only 'ID' is supported.
- `description` (String) A description of the template, along with when and why it should be used, up to 500 characters
- `labels` (List of String) List of labels attached to this Template.
- `project_id` (String) The ID of the HCP project where the Waypoint Template is located.
Expand Down
32 changes: 30 additions & 2 deletions internal/provider/waypoint/data_source_waypoint_application.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ func (d *DataSourceApplication) Schema(ctx context.Context, req datasource.Schem
Computed: true,
Description: "Internal Namespace ID.",
},
"actions": schema.ListAttribute{
Optional: true,
Description: "List of actions by 'ID' to assign to this Template. " +
"Applications created from this Template will have these actions " +
"assigned to them. Only 'ID' is supported.",
ElementType: types.StringType,
},
"input_variables": schema.SetNestedAttribute{
Optional: true,
Description: "Input variables for the Application.",
Expand Down Expand Up @@ -156,6 +163,7 @@ type ApplicationDataSourceModel struct {
TemplateID types.String `tfsdk:"template_id"`
TemplateName types.String `tfsdk:"template_name"`
NamespaceID types.String `tfsdk:"namespace_id"`
Actions types.List `tfsdk:"actions"`

// deferred for now
// Tags types.List `tfsdk:"tags"`
Expand Down Expand Up @@ -206,6 +214,26 @@ func (d *DataSourceApplication) Read(ctx context.Context, req datasource.ReadReq
data.ID = types.StringValue(application.ID)
data.OrgID = types.StringValue(client.Config.OrganizationID)
data.ProjectID = types.StringValue(client.Config.ProjectID)

data.Actions = types.ListNull(types.StringType)
if application.ActionCfgRefs != nil {
var actionIDs []string
for _, action := range application.ActionCfgRefs {
actionIDs = append(actionIDs, action.ID)
}

actions, diags := types.ListValueFrom(ctx, types.StringType, actionIDs)
resp.Diagnostics.Append(diags...)
if diags.HasError() {
return
}
if len(actions.Elements()) == 0 {
data.Actions = types.ListNull(types.StringType)
} else {
data.Actions = actions
}
}

// set data.readme if it's not null or application.readme is not
// empty
data.ReadmeMarkdown = types.StringValue(application.ReadmeMarkdown.String())
Expand All @@ -220,6 +248,8 @@ func (d *DataSourceApplication) Read(ctx context.Context, req datasource.ReadReq
return
}

var diags diag.Diagnostics

inputVariables := make([]*InputVar, 0)
for _, iv := range inputVars {
inputVariables = append(inputVariables, &InputVar{
Expand All @@ -238,8 +268,6 @@ func (d *DataSourceApplication) Read(ctx context.Context, req datasource.ReadReq
data.InputVars = types.SetNull(types.ObjectType{AttrTypes: InputVar{}.attrTypes()})
}

var diags diag.Diagnostics

// Read the output values from the application and set them in the plan
ol := readOutputs(application.OutputValues)
if len(ol) > 0 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/hashicorp/terraform-provider-hcp/internal/provider/acctest"
"github.com/hashicorp/terraform-provider-hcp/internal/provider/waypoint"
)
Expand Down Expand Up @@ -81,6 +82,59 @@ func TestAcc_Waypoint_Application_DataSource_WithInputVars(t *testing.T) {
})
}

func TestAcc_Waypoint_Application_DataSource_WithActions(t *testing.T) {
t.Parallel()

var (
appTemplateModel waypoint.TemplateResourceModel
applicationModel waypoint.ApplicationResourceModel
actionCfgModel waypoint.ActionResourceModel
)
templateResourceName := "hcp_waypoint_template.actions_template_test"
resourceName := "hcp_waypoint_application.actions_application_test"
actionResourceName := "hcp_waypoint_action.test"
dataSourceName := "data." + resourceName
templateName := generateRandomName()
applicationName := generateRandomName()
actionName := generateRandomName()

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories,
CheckDestroy: func(s *terraform.State) error {
if err := testAccCheckWaypointApplicationDestroy(t, &applicationModel)(s); err != nil {
return err
}
if err := testAccCheckWaypointTemplateDestroy(t, &appTemplateModel)(s); err != nil {
return err
}
if err := testAccCheckWaypointActionDestroy(t, &actionCfgModel)(s); err != nil {
return err
}
return nil
},
Steps: []resource.TestStep{
{
// establish the base template and app
Config: testTemplateWithAppAndActionsConfig(templateName, applicationName, actionName),
Check: resource.ComposeTestCheckFunc(
testAccCheckWaypointApplicationExists(t, resourceName, &applicationModel),
testAccCheckWaypointTemplateExists(t, templateResourceName, &appTemplateModel),
testAccCheckWaypointActionExists(t, actionResourceName, &actionCfgModel),
),
},
{
// add a data source config to read the template
Config: testDataApplicationWithAction(templateName, applicationName, actionName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "name", applicationName),
resource.TestCheckResourceAttr(dataSourceName, "actions.#", "1"),
),
},
},
})
}

func testDataApplicationConfig(templateName, applicationName string) string {
return fmt.Sprintf(`%s

Expand All @@ -96,3 +150,11 @@ data "hcp_waypoint_application" "test_var_opts" {
name = hcp_waypoint_application.test_var_opts.name
}`, testApplicationWithInputVarsConfig(templateName, applicationName))
}

func testDataApplicationWithAction(templateName, applicationName, actionName string) string {
return fmt.Sprintf(`%s

data "hcp_waypoint_application" "actions_application_test" {
name = hcp_waypoint_application.actions_application_test.name
}`, testTemplateWithAppAndActionsConfig(templateName, applicationName, actionName))
}
26 changes: 26 additions & 0 deletions internal/provider/waypoint/data_source_waypoint_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type DataSourceTemplateModel struct {
Labels types.List `tfsdk:"labels"`
Description types.String `tfsdk:"description"`
ReadmeMarkdownTemplate types.String `tfsdk:"readme_markdown_template"`
Actions types.List `tfsdk:"actions"`

TerraformCloudWorkspace *tfcWorkspace `tfsdk:"terraform_cloud_workspace_details"`
TerraformNoCodeModuleSource types.String `tfsdk:"terraform_no_code_module_source"`
Expand Down Expand Up @@ -95,6 +96,13 @@ func (d *DataSourceTemplate) Schema(ctx context.Context, req datasource.SchemaRe
Computed: true,
Description: "Instructions for using the template (markdown format supported)",
},
"actions": schema.ListAttribute{
Optional: true,
Description: "List of actions by 'ID' to assign to this Template. " +
"Applications created from this Template will have these actions " +
"assigned to them. Only 'ID' is supported.",
ElementType: types.StringType,
},
"labels": schema.ListAttribute{
Computed: true,
Description: "List of labels attached to this Template.",
Expand Down Expand Up @@ -242,6 +250,24 @@ func (d *DataSourceTemplate) Read(ctx context.Context, req datasource.ReadReques
}
data.Labels = labels

data.Actions = types.ListNull(types.StringType)
if appTemplate.ActionCfgRefs != nil {
var actionIDs []string
for _, action := range appTemplate.ActionCfgRefs {
actionIDs = append(actionIDs, action.ID)
}

actions, diags := types.ListValueFrom(ctx, types.StringType, actionIDs)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
if len(actions.Elements()) == 0 {
actions = types.ListNull(types.StringType)
}
data.Actions = actions
}

// set data.description if it's not null or appTemplate.description is not
// empty
data.Description = types.StringValue(appTemplate.Description)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/hashicorp/terraform-provider-hcp/internal/provider/acctest"
"github.com/hashicorp/terraform-provider-hcp/internal/provider/waypoint"
)
Expand Down Expand Up @@ -96,7 +97,52 @@ func TestAcc_Waypoint_Data_template_with_variable_options(t *testing.T) {
},
},
})
}

func TestAcc_Waypoint_Data_template_with_actions(t *testing.T) {
t.Parallel()

var (
appTemplateModel waypoint.TemplateResourceModel
actionCfgModel waypoint.ActionResourceModel
)
resourceName := "hcp_waypoint_template.actions_template_test"
actionResourceName := "hcp_waypoint_action.test"
dataSourceName := "data." + resourceName
name := generateRandomName()
actionName := generateRandomName()

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories,
CheckDestroy: func(s *terraform.State) error {
if err := testAccCheckWaypointTemplateDestroy(t, &appTemplateModel)(s); err != nil {
return err
}
if err := testAccCheckWaypointActionDestroy(t, &actionCfgModel)(s); err != nil {
return err
}
return nil
},
Steps: []resource.TestStep{
{
// establish the base template
Config: testTemplateWithActionsConfig(name, actionName),
Check: resource.ComposeTestCheckFunc(
testAccCheckWaypointTemplateExists(t, resourceName, &appTemplateModel),
testAccCheckWaypointActionExists(t, actionResourceName, &actionCfgModel),
),
},
{
// add a data source config to read the template
Config: testDataAppTemplateWithAction(name, actionName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "name", name),
resource.TestCheckResourceAttr(dataSourceName, "actions.#", "1"),
),
},
},
})
}

func testDataAppTemplateConfig(name string) string {
Expand All @@ -112,3 +158,10 @@ data "hcp_waypoint_template" "var_opts_test" {
name = hcp_waypoint_template.var_opts_test.name
}`, testTemplateConfigWithVarOpts(name))
}

func testDataAppTemplateWithAction(templateName, actionName string) string {
return fmt.Sprintf(`%s
data "hcp_waypoint_template" "actions_template_test" {
name = hcp_waypoint_template.actions_template_test.name
}`, testTemplateWithActionsConfig(templateName, actionName))
}
Loading