Skip to content

Commit 6628de2

Browse files
HenryEstbergPier-Luc Caron-St-Pierre
andauthored
HCP Waypoint agent actions support (#1304)
Adding agent flavored action support to the provider Co-authored-by: Pier-Luc Caron-St-Pierre <pier-luc.caronst-pierre@hashicorp.com>
1 parent 9409f82 commit 6628de2

19 files changed

+1074
-37
lines changed

.changelog/1304.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:feature
2+
Add support for agent actions in HCP Waypoint
3+
```

docs/data-sources/waypoint_action.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ description: |-
77

88
# hcp_waypoint_action `Data Source`
99

10-
-> **Note:** HCP Waypoint actions is currently in beta.
11-
1210
The Waypoint Action data source retrieves information on a given Action.
1311

1412
<!-- schema generated by tfplugindocs -->
@@ -18,21 +16,36 @@ The Waypoint Action data source retrieves information on a given Action.
1816

1917
- `id` (String) The ID of the Action.
2018
- `name` (String) The name of the Action.
21-
- `project_id` (String) The ID of the HCP project where the Waypoint Action is located.
2219

2320
### Read-Only
2421

2522
- `description` (String) A description of the Action.
2623
- `organization_id` (String) The ID of the HCP organization where the Waypoint Action is located.
24+
- `project_id` (String) The ID of the HCP project where the Waypoint Action is located.
2725
- `request` (Attributes) The kind of HTTP request this should trigger. (see [below for nested schema](#nestedatt--request))
2826

2927
<a id="nestedatt--request"></a>
3028
### Nested Schema for `request`
3129

30+
Optional:
31+
32+
- `agent` (Attributes) Agent mode allows users to define the agent to use for the request. (see [below for nested schema](#nestedatt--request--agent))
33+
3234
Read-Only:
3335

3436
- `custom` (Attributes) Custom mode allows users to define the HTTP method, the request body, etc. (see [below for nested schema](#nestedatt--request--custom))
3537

38+
<a id="nestedatt--request--agent"></a>
39+
### Nested Schema for `request.agent`
40+
41+
Read-Only:
42+
43+
- `action_run_id` (String) An optional action run id. If specified the agent will interact with the actions subsystem.
44+
- `body` (String) Arguments to the operation, specified as JSON.
45+
- `group` (String) The name of the group that the operation is in.
46+
- `operation_id` (String) The identifying name of the operation in the agent config file.
47+
48+
3649
<a id="nestedatt--request--custom"></a>
3750
### Nested Schema for `request.custom`
3851

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
page_title: "hcp_waypoint_agent_group Data Source - terraform-provider-hcp"
3+
subcategory: "HCP Waypoint"
4+
description: |-
5+
The Waypoint Agent Group resource manages the lifecycle of an Agent Group.
6+
---
7+
8+
# hcp_waypoint_agent_group `Data Source`
9+
10+
The Waypoint Agent Group resource manages the lifecycle of an Agent Group.
11+
12+
<!-- schema generated by tfplugindocs -->
13+
## Schema
14+
15+
### Required
16+
17+
- `name` (String) The name of the Agent Group.
18+
19+
### Read-Only
20+
21+
- `description` (String) A description of the Agent Group.
22+
- `organization_id` (String) The ID of the Waypoint organization to which the Agent Group belongs.
23+
- `project_id` (String) The ID of the Waypoint project to which the Agent Group belongs.

docs/resources/waypoint_action.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ description: |-
77

88
# hcp_waypoint_action `Resource`
99

10-
-> **Note:** HCP Waypoint actions is currently in beta.
11-
1210
The Waypoint Action resource manages the lifecycle of an Action.
1311

1412
<!-- schema generated by tfplugindocs -->
@@ -34,8 +32,23 @@ The Waypoint Action resource manages the lifecycle of an Action.
3432

3533
Optional:
3634

35+
- `agent` (Attributes) Agent mode allows users to define the agent to use for the request. (see [below for nested schema](#nestedatt--request--agent))
3736
- `custom` (Attributes) Custom mode allows users to define the HTTP method, the request body, etc. (see [below for nested schema](#nestedatt--request--custom))
3837

38+
<a id="nestedatt--request--agent"></a>
39+
### Nested Schema for `request.agent`
40+
41+
Required:
42+
43+
- `group` (String) The name of the group that the operation is in.
44+
- `operation_id` (String) The identifying name of the operation in the agent config file.
45+
46+
Optional:
47+
48+
- `action_run_id` (String) An optional action run id. If specified the agent will interact with the actions subsystem.
49+
- `body` (String) Arguments to the operation, specified as JSON.
50+
51+
3952
<a id="nestedatt--request--custom"></a>
4053
### Nested Schema for `request.custom`
4154

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
page_title: "hcp_waypoint_agent_group Resource - terraform-provider-hcp"
3+
subcategory: "HCP Waypoint"
4+
description: |-
5+
The Waypoint Agent Group resource manages the lifecycle of an Agent Group.
6+
---
7+
8+
# hcp_waypoint_agent_group `Resource`
9+
10+
The Waypoint Agent Group resource manages the lifecycle of an Agent Group.
11+
12+
<!-- schema generated by tfplugindocs -->
13+
## Schema
14+
15+
### Required
16+
17+
- `name` (String) The name of the Agent Group.
18+
19+
### Optional
20+
21+
- `description` (String) A description of the Agent Group.
22+
- `organization_id` (String) The ID of the Waypoint organization to which the Agent Group belongs.
23+
- `project_id` (String) The ID of the Waypoint project to which the Agent Group belongs.

internal/clients/waypoint.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@ func GetAction(ctx context.Context, client *Client, loc *sharedmodels.HashicorpC
2828
return getResp.GetPayload().ActionConfig, nil
2929
}
3030

31+
// GetAgentGroup will retrieve an Agent Group by name
32+
func GetAgentGroup(ctx context.Context, client *Client, loc *sharedmodels.HashicorpCloudLocationLocation, groupName string) (*waypoint_models.HashicorpCloudWaypointV20241122AgentGroup, error) {
33+
params := &waypoint_service.WaypointServiceGetAgentGroupParams{
34+
Name: groupName,
35+
NamespaceLocationOrganizationID: loc.OrganizationID,
36+
NamespaceLocationProjectID: loc.ProjectID,
37+
}
38+
39+
getResp, err := client.Waypoint.WaypointServiceGetAgentGroup(params, nil)
40+
if err != nil {
41+
return nil, err
42+
}
43+
return getResp.GetPayload().Group, nil
44+
}
45+
3146
// GetApplicationTemplateByName will retrieve a template by name
3247
func GetApplicationTemplateByName(ctx context.Context, client *Client, loc *sharedmodels.HashicorpCloudLocationLocation, appName string) (*waypoint_models.HashicorpCloudWaypointV20241122ApplicationTemplate, error) {
3348
params := &waypoint_service.WaypointServiceGetApplicationTemplate2Params{

internal/provider/provider.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ func (p *ProviderFramework) Resources(ctx context.Context) []func() resource.Res
181181
webhook.NewNotificationsWebhookResource,
182182
// Waypoint
183183
waypoint.NewActionResource,
184+
waypoint.NewAgentGroupResource,
184185
waypoint.NewApplicationResource,
185186
waypoint.NewTemplateResource,
186187
waypoint.NewAddOnResource,
@@ -215,6 +216,7 @@ func (p *ProviderFramework) DataSources(ctx context.Context) []func() datasource
215216
iam.NewUserPrincipalDataSource,
216217
// Waypoint
217218
waypoint.NewActionDataSource,
219+
waypoint.NewAgentGroupDataSource,
218220
waypoint.NewApplicationDataSource,
219221
waypoint.NewTemplateDataSource,
220222
waypoint.NewAddOnDataSource,

internal/provider/waypoint/data_source_waypoint_action.go

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ func (d *DataSourceAction) Schema(ctx context.Context, req datasource.SchemaRequ
6262
},
6363
"project_id": schema.StringAttribute{
6464
Description: "The ID of the HCP project where the Waypoint Action is located.",
65-
Optional: true,
6665
Computed: true,
6766
},
6867
"description": schema.StringAttribute{
@@ -96,6 +95,28 @@ func (d *DataSourceAction) Schema(ctx context.Context, req datasource.SchemaRequ
9695
},
9796
},
9897
},
98+
"agent": schema.SingleNestedAttribute{
99+
Description: "Agent mode allows users to define the agent to use for the request.",
100+
Optional: true,
101+
Attributes: map[string]schema.Attribute{
102+
"operation_id": schema.StringAttribute{
103+
Description: "The identifying name of the operation in the agent config file.",
104+
Computed: true,
105+
},
106+
"body": schema.StringAttribute{
107+
Description: "Arguments to the operation, specified as JSON.",
108+
Computed: true,
109+
},
110+
"action_run_id": schema.StringAttribute{
111+
Description: "An optional action run id. If specified the agent will interact with the actions subsystem.",
112+
Computed: true,
113+
},
114+
"group": schema.StringAttribute{
115+
Description: "The name of the group that the operation is in.",
116+
Computed: true,
117+
},
118+
},
119+
},
99120
},
100121
},
101122
},
@@ -119,7 +140,7 @@ func (d *DataSourceAction) Configure(ctx context.Context, req datasource.Configu
119140
}
120141

121142
func (d *DataSourceAction) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
122-
var data ActionResourceModel
143+
var data *ActionResourceModel
123144

124145
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
125146

@@ -159,36 +180,24 @@ func (d *DataSourceAction) Read(ctx context.Context, req datasource.ReadRequest,
159180
data.ProjectID = types.StringValue(client.Config.ProjectID)
160181

161182
data.Request = &actionRequest{}
162-
headerMap := make(map[string]string)
163183

164184
var diags diag.Diagnostics
165185

166186
// In the future, expand this to accommodate other types of requests
167187

168-
data.Request.Custom = &customRequest{}
169-
if actionModel.Request.Custom.Method != nil {
170-
data.Request.Custom.Method = types.StringValue(string(*actionModel.Request.Custom.Method))
171-
} else {
172-
data.Request.Custom.Method = types.StringNull()
173-
}
174-
if actionModel.Request.Custom.Headers != nil {
175-
for _, header := range actionModel.Request.Custom.Headers {
176-
headerMap[header.Key] = header.Value
188+
if actionModel.Request.Custom != nil {
189+
diags = readCustomAction(ctx, data, actionModel)
190+
if diags.HasError() {
191+
resp.Diagnostics.Append(diags...)
192+
return
177193
}
178-
if len(headerMap) > 0 {
179-
data.Request.Custom.Headers, diags = types.MapValueFrom(ctx, types.StringType, headerMap)
194+
} else if actionModel.Request.Agent != nil {
195+
diags = readAgentAction(ctx, data, actionModel)
196+
if diags.HasError() {
180197
resp.Diagnostics.Append(diags...)
181-
if resp.Diagnostics.HasError() {
182-
return
183-
}
184-
} else {
185-
data.Request.Custom.Headers = types.MapNull(types.StringType)
198+
return
186199
}
187-
} else {
188-
data.Request.Custom.Headers = types.MapNull(types.StringType)
189200
}
190-
data.Request.Custom.URL = types.StringValue(actionModel.Request.Custom.URL)
191-
data.Request.Custom.Body = types.StringValue(actionModel.Request.Custom.Body)
192201

193202
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
194203
}

internal/provider/waypoint/data_source_waypoint_action_test.go

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,54 @@ func TestAcc_Waypoint_Action_DataSource_basic(t *testing.T) {
5151
})
5252
}
5353

54+
func TestAcc_Waypoint_Action_DataSource_Agent(t *testing.T) {
55+
t.Parallel()
56+
57+
// Skip this test unless the appropriate environment variable is set
58+
// This is to prevent running this test by default
59+
if os.Getenv("HCP_WAYP_ACTION_TEST") == "" {
60+
t.Skipf("Waypoint Action tests skipped unless env '%s' set",
61+
"HCP_WAYP_ACTION_TEST")
62+
return
63+
}
64+
var actionModel waypoint.ActionResourceModel
65+
resourceName := "hcp_waypoint_action.test_agent"
66+
dataSourceName := "data." + resourceName
67+
actionName := generateRandomName()
68+
69+
resource.Test(t, resource.TestCase{
70+
PreCheck: func() { acctest.PreCheck(t) },
71+
ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories,
72+
CheckDestroy: testAccCheckWaypointActionDestroy(t, &actionModel),
73+
Steps: []resource.TestStep{
74+
{
75+
// establish the base action config with agent
76+
Config: testAgentAction(actionName),
77+
Check: resource.ComposeTestCheckFunc(
78+
testAccCheckWaypointActionExists(t, resourceName, &actionModel),
79+
),
80+
},
81+
{
82+
// add a data source config to read the action config with agent
83+
Config: testDataActionConfigAgent(actionName),
84+
Check: resource.ComposeTestCheckFunc(
85+
resource.TestCheckResourceAttr(dataSourceName, "name", actionName),
86+
),
87+
},
88+
},
89+
})
90+
}
91+
5492
func testDataActionConfig(actionName string) string {
5593
return fmt.Sprintf(`%s
56-
5794
data "hcp_waypoint_action" "test" {
5895
name = hcp_waypoint_action.test.name
5996
}`, testAction(actionName))
6097
}
98+
99+
func testDataActionConfigAgent(actionName string) string {
100+
return fmt.Sprintf(`%s
101+
data "hcp_waypoint_action" "test_agent" {
102+
name = hcp_waypoint_action.test_agent.name
103+
}`, testAgentAction(actionName))
104+
}

0 commit comments

Comments
 (0)