Skip to content

Commit 955be97

Browse files
committed
impl fw data_source.enrollment_tokens
1 parent 57dae5d commit 955be97

File tree

10 files changed

+267
-146
lines changed

10 files changed

+267
-146
lines changed

internal/clients/fleet/fleet.go

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net/http"
99

1010
fleetapi "github.com/elastic/terraform-provider-elasticstack/generated/fleet"
11+
fwdiag "github.com/hashicorp/terraform-plugin-framework/diag"
1112
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1213
)
1314

@@ -16,20 +17,20 @@ var (
1617
)
1718

1819
// AllEnrollmentTokens reads all enrollment tokens from the API.
19-
func AllEnrollmentTokens(ctx context.Context, client *Client) ([]fleetapi.EnrollmentApiKey, diag.Diagnostics) {
20+
func AllEnrollmentTokens(ctx context.Context, client *Client) ([]fleetapi.EnrollmentApiKey, fwdiag.Diagnostics) {
2021
resp, err := client.API.GetEnrollmentApiKeysWithResponse(ctx)
2122
if err != nil {
22-
return nil, diag.FromErr(err)
23+
return nil, fromErr(err)
2324
}
2425

2526
if resp.StatusCode() == http.StatusOK {
2627
return resp.JSON200.Items, nil
2728
}
28-
return nil, reportUnknownError(resp.StatusCode(), resp.Body)
29+
return nil, reportUnknownErrorFw(resp.StatusCode(), resp.Body)
2930
}
3031

3132
// GetEnrollmentTokensByPolicy Get enrollment tokens by given policy ID
32-
func GetEnrollmentTokensByPolicy(ctx context.Context, client *Client, policyID string) ([]fleetapi.EnrollmentApiKey, diag.Diagnostics) {
33+
func GetEnrollmentTokensByPolicy(ctx context.Context, client *Client, policyID string) ([]fleetapi.EnrollmentApiKey, fwdiag.Diagnostics) {
3334
resp, err := client.API.GetEnrollmentApiKeysWithResponse(ctx, func(ctx context.Context, req *http.Request) error {
3435
q := req.URL.Query()
3536
q.Set("kuery", "policy_id:"+policyID)
@@ -38,13 +39,13 @@ func GetEnrollmentTokensByPolicy(ctx context.Context, client *Client, policyID s
3839
return nil
3940
})
4041
if err != nil {
41-
return nil, diag.FromErr(err)
42+
return nil, fromErr(err)
4243
}
4344

4445
if resp.StatusCode() == http.StatusOK {
4546
return resp.JSON200.Items, nil
4647
}
47-
return nil, reportUnknownError(resp.StatusCode(), resp.Body)
48+
return nil, reportUnknownErrorFw(resp.StatusCode(), resp.Body)
4849
}
4950

5051
// ReadAgentPolicy reads a specific agent policy from the API.
@@ -416,6 +417,16 @@ func AllPackages(ctx context.Context, client *Client, prerelease bool) ([]fleeta
416417
}
417418
}
418419

420+
// fromErr recreates the sdkdiag.FromErr functionality.
421+
func fromErr(err error) fwdiag.Diagnostics {
422+
if err == nil {
423+
return nil
424+
}
425+
return fwdiag.Diagnostics{
426+
fwdiag.NewErrorDiagnostic(err.Error(), ""),
427+
}
428+
}
429+
419430
func reportUnknownError(statusCode int, body []byte) diag.Diagnostics {
420431
return diag.Diagnostics{
421432
diag.Diagnostic{
@@ -425,3 +436,12 @@ func reportUnknownError(statusCode int, body []byte) diag.Diagnostics {
425436
},
426437
}
427438
}
439+
440+
func reportUnknownErrorFw(statusCode int, body []byte) fwdiag.Diagnostics {
441+
return fwdiag.Diagnostics{
442+
fwdiag.NewErrorDiagnostic(
443+
fmt.Sprintf("Unexpected status code from server: got HTTP %d", statusCode),
444+
string(body),
445+
),
446+
}
447+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package enrollment_tokens
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/elastic/terraform-provider-elasticstack/internal/clients"
8+
"github.com/hashicorp/terraform-plugin-framework/datasource"
9+
)
10+
11+
var (
12+
_ datasource.DataSource = &dataSource{}
13+
_ datasource.DataSourceWithConfigure = &dataSource{}
14+
)
15+
16+
// NewDataSource is a helper function to simplify the provider implementation.
17+
func NewDataSource() datasource.DataSource {
18+
return &dataSource{}
19+
}
20+
21+
type dataSource struct {
22+
client *clients.ApiClient
23+
}
24+
25+
func (d *dataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
26+
resp.TypeName = fmt.Sprintf("%s_%s", req.ProviderTypeName, "fleet_enrollment_tokens")
27+
}
28+
29+
func (d *dataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
30+
client, diags := clients.ConvertProviderData(req.ProviderData)
31+
resp.Diagnostics.Append(diags...)
32+
d.client = client
33+
}

internal/fleet/enrollment_tokens_data_source_test.go renamed to internal/fleet/enrollment_tokens/data_source_test.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1-
package fleet_test
1+
package enrollment_tokens_test
22

33
import (
4+
"context"
5+
"fmt"
46
"testing"
57

68
"github.com/elastic/terraform-provider-elasticstack/internal/acctest"
9+
"github.com/elastic/terraform-provider-elasticstack/internal/clients"
10+
"github.com/elastic/terraform-provider-elasticstack/internal/clients/fleet"
11+
"github.com/elastic/terraform-provider-elasticstack/internal/utils"
712
"github.com/elastic/terraform-provider-elasticstack/internal/versionutils"
813
"github.com/hashicorp/go-version"
914
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
15+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
1016
)
1117

1218
var minVersionEnrollmentTokens = version.Must(version.NewVersion("8.6.0"))
@@ -46,3 +52,29 @@ data "elasticstack_fleet_enrollment_tokens" "test" {
4652
policy_id = elasticstack_fleet_agent_policy.test.policy_id
4753
}
4854
`
55+
56+
func checkResourceAgentPolicyDestroy(s *terraform.State) error {
57+
client, err := clients.NewAcceptanceTestingClient()
58+
if err != nil {
59+
return err
60+
}
61+
62+
for _, rs := range s.RootModule().Resources {
63+
if rs.Type != "elasticstack_fleet_agent_policy" {
64+
continue
65+
}
66+
67+
fleetClient, err := client.GetFleetClient()
68+
if err != nil {
69+
return err
70+
}
71+
policy, diags := fleet.ReadAgentPolicy(context.Background(), fleetClient, rs.Primary.ID)
72+
if diags.HasError() {
73+
return utils.SdkDiagsAsError(diags)
74+
}
75+
if policy != nil {
76+
return fmt.Errorf("agent policy id=%v still exists, but it should have been removed", rs.Primary.ID)
77+
}
78+
}
79+
return nil
80+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package enrollment_tokens
2+
3+
import (
4+
fleetapi "github.com/elastic/terraform-provider-elasticstack/generated/fleet"
5+
"github.com/hashicorp/terraform-plugin-framework/types"
6+
)
7+
8+
type enrollmentTokensModel struct {
9+
ID types.String `tfsdk:"id"`
10+
PolicyID types.String `tfsdk:"policy_id"`
11+
Tokens []enrollmentTokenModel `tfsdk:"tokens"`
12+
}
13+
14+
type enrollmentTokenModel struct {
15+
KeyID types.String `tfsdk:"key_id"`
16+
ApiKey types.String `tfsdk:"api_key"`
17+
ApiKeyID types.String `tfsdk:"api_key_id"`
18+
CreatedAt types.String `tfsdk:"created_at"`
19+
Name types.String `tfsdk:"name"`
20+
Active types.Bool `tfsdk:"active"`
21+
PolicyID types.String `tfsdk:"policy_id"`
22+
}
23+
24+
func (model *enrollmentTokensModel) populateFromAPI(data []fleetapi.EnrollmentApiKey) {
25+
model.Tokens = make([]enrollmentTokenModel, 0, len(data))
26+
for _, token := range data {
27+
itemModel := enrollmentTokenModel{}
28+
itemModel.populateFromAPI(token)
29+
model.Tokens = append(model.Tokens, itemModel)
30+
}
31+
}
32+
33+
func (model *enrollmentTokenModel) populateFromAPI(data fleetapi.EnrollmentApiKey) {
34+
model.KeyID = types.StringValue(data.Id)
35+
model.Active = types.BoolValue(data.Active)
36+
model.ApiKey = types.StringValue(data.ApiKey)
37+
model.ApiKeyID = types.StringValue(data.ApiKeyId)
38+
model.CreatedAt = types.StringValue(data.CreatedAt)
39+
model.Name = types.StringPointerValue(data.Name)
40+
model.PolicyID = types.StringPointerValue(data.PolicyId)
41+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package enrollment_tokens
2+
3+
import (
4+
"context"
5+
6+
fleetapi "github.com/elastic/terraform-provider-elasticstack/generated/fleet"
7+
"github.com/elastic/terraform-provider-elasticstack/internal/clients/fleet"
8+
"github.com/elastic/terraform-provider-elasticstack/internal/utils"
9+
"github.com/hashicorp/terraform-plugin-framework/datasource"
10+
"github.com/hashicorp/terraform-plugin-framework/types"
11+
)
12+
13+
func (d *dataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
14+
var model enrollmentTokensModel
15+
16+
diags := req.Config.Get(ctx, &model)
17+
resp.Diagnostics.Append(diags...)
18+
if resp.Diagnostics.HasError() {
19+
return
20+
}
21+
22+
client, err := d.client.GetFleetClient()
23+
if err != nil {
24+
resp.Diagnostics.AddError(err.Error(), "")
25+
return
26+
}
27+
28+
var tokens []fleetapi.EnrollmentApiKey
29+
policyID := model.PolicyID.ValueString()
30+
if policyID == "" {
31+
tokens, diags = fleet.AllEnrollmentTokens(ctx, client)
32+
} else {
33+
tokens, diags = fleet.GetEnrollmentTokensByPolicy(ctx, client, policyID)
34+
}
35+
resp.Diagnostics.Append(diags...)
36+
if resp.Diagnostics.HasError() {
37+
return
38+
}
39+
40+
if policyID != "" {
41+
model.ID = types.StringValue(policyID)
42+
} else {
43+
hash, err := utils.StringToHash(client.URL)
44+
if err != nil {
45+
resp.Diagnostics.AddError(err.Error(), "")
46+
return
47+
}
48+
model.ID = types.StringPointerValue(hash)
49+
}
50+
51+
model.populateFromAPI(tokens)
52+
53+
diags = resp.State.Set(ctx, model)
54+
resp.Diagnostics.Append(diags...)
55+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package enrollment_tokens
2+
3+
import (
4+
"context"
5+
6+
"github.com/hashicorp/terraform-plugin-framework/datasource"
7+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
8+
)
9+
10+
func (d *dataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
11+
resp.Schema.Description = "Retrieves Elasticsearch API keys used to enroll Elastic Agents in Fleet. See: https://www.elastic.co/guide/en/fleet/current/fleet-enrollment-tokens.html"
12+
resp.Schema.Attributes = map[string]schema.Attribute{
13+
"id": schema.StringAttribute{
14+
Description: "The ID of this resource.",
15+
Computed: true,
16+
},
17+
"policy_id": schema.StringAttribute{
18+
Description: "The identifier of the target agent policy. When provided, only the enrollment tokens associated with this agent policy will be selected. Omit this value to select all enrollment tokens.",
19+
Optional: true,
20+
},
21+
"tokens": schema.ListNestedAttribute{
22+
Description: "A list of enrollment tokens.",
23+
Computed: true,
24+
NestedObject: schema.NestedAttributeObject{
25+
Attributes: map[string]schema.Attribute{
26+
"key_id": schema.StringAttribute{
27+
Description: "The unique identifier of the enrollment token.",
28+
Computed: true,
29+
},
30+
"api_key": schema.StringAttribute{
31+
Description: "The API key.",
32+
Computed: true,
33+
Sensitive: true,
34+
},
35+
"api_key_id": schema.StringAttribute{
36+
Description: "The API key identifier.",
37+
Computed: true,
38+
},
39+
"created_at": schema.StringAttribute{
40+
Description: "The time at which the enrollment token was created.",
41+
Computed: true,
42+
},
43+
"name": schema.StringAttribute{
44+
Description: "The name of the enrollment token.",
45+
Computed: true,
46+
},
47+
"active": schema.BoolAttribute{
48+
Description: "Indicates if the enrollment token is active.",
49+
Computed: true,
50+
},
51+
"policy_id": schema.StringAttribute{
52+
Description: "The identifier of the associated agent policy.",
53+
Computed: true,
54+
},
55+
},
56+
},
57+
},
58+
}
59+
}

0 commit comments

Comments
 (0)