Skip to content

Commit c2f50df

Browse files
committed
impl fw resource/data_source integration
1 parent eabca1f commit c2f50df

File tree

18 files changed

+432
-238
lines changed

18 files changed

+432
-238
lines changed

internal/clients/fleet/fleet.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -333,32 +333,32 @@ func DeletePackagePolicy(ctx context.Context, client *Client, id string, force b
333333
}
334334

335335
// ReadPackage reads a specific package from the API.
336-
func ReadPackage(ctx context.Context, client *Client, name, version string) diag.Diagnostics {
336+
func ReadPackage(ctx context.Context, client *Client, name, version string) fwdiag.Diagnostics {
337337
params := fleetapi.GetPackageParams{}
338338

339339
resp, err := client.API.GetPackage(ctx, name, version, &params)
340340
if err != nil {
341-
return diag.FromErr(err)
341+
return fromErr(err)
342342
}
343343
defer resp.Body.Close()
344344

345345
switch resp.StatusCode {
346346
case http.StatusOK:
347347
return nil
348348
case http.StatusNotFound:
349-
return diag.FromErr(ErrPackageNotFound)
349+
return fromErr(ErrPackageNotFound)
350350
default:
351351
errData, err := io.ReadAll(resp.Body)
352352
if err != nil {
353-
return diag.FromErr(err)
353+
return fromErr(err)
354354
}
355355

356-
return reportUnknownError(resp.StatusCode, errData)
356+
return reportUnknownErrorFw(resp.StatusCode, errData)
357357
}
358358
}
359359

360360
// InstallPackage installs a package.
361-
func InstallPackage(ctx context.Context, client *Client, name, version string, force bool) diag.Diagnostics {
361+
func InstallPackage(ctx context.Context, client *Client, name, version string, force bool) fwdiag.Diagnostics {
362362
params := fleetapi.InstallPackageParams{}
363363
body := fleetapi.InstallPackageJSONRequestBody{
364364
Force: &force,
@@ -367,7 +367,7 @@ func InstallPackage(ctx context.Context, client *Client, name, version string, f
367367

368368
resp, err := client.API.InstallPackage(ctx, name, version, &params, body)
369369
if err != nil {
370-
return diag.FromErr(err)
370+
return fromErr(err)
371371
}
372372
defer resp.Body.Close()
373373

@@ -377,23 +377,23 @@ func InstallPackage(ctx context.Context, client *Client, name, version string, f
377377
default:
378378
errData, err := io.ReadAll(resp.Body)
379379
if err != nil {
380-
return diag.FromErr(err)
380+
return fromErr(err)
381381
}
382382

383-
return reportUnknownError(resp.StatusCode, errData)
383+
return reportUnknownErrorFw(resp.StatusCode, errData)
384384
}
385385
}
386386

387387
// Uninstall uninstalls a package.
388-
func Uninstall(ctx context.Context, client *Client, name, version string, force bool) diag.Diagnostics {
388+
func Uninstall(ctx context.Context, client *Client, name, version string, force bool) fwdiag.Diagnostics {
389389
params := fleetapi.DeletePackageParams{}
390390
body := fleetapi.DeletePackageJSONRequestBody{
391391
Force: &force,
392392
}
393393

394394
resp, err := client.API.DeletePackageWithResponse(ctx, name, version, &params, body)
395395
if err != nil {
396-
return diag.FromErr(err)
396+
return fromErr(err)
397397
}
398398

399399
switch resp.StatusCode() {
@@ -402,26 +402,26 @@ func Uninstall(ctx context.Context, client *Client, name, version string, force
402402
case http.StatusNotFound:
403403
return nil
404404
default:
405-
return reportUnknownError(resp.StatusCode(), resp.Body)
405+
return reportUnknownErrorFw(resp.StatusCode(), resp.Body)
406406
}
407407
}
408408

409409
// AllPackages returns information about the latest packages known to Fleet.
410-
func AllPackages(ctx context.Context, client *Client, prerelease bool) ([]fleetapi.SearchResult, diag.Diagnostics) {
410+
func AllPackages(ctx context.Context, client *Client, prerelease bool) ([]fleetapi.SearchResult, fwdiag.Diagnostics) {
411411
params := fleetapi.ListAllPackagesParams{
412412
Prerelease: &prerelease,
413413
}
414414

415415
resp, err := client.API.ListAllPackagesWithResponse(ctx, &params)
416416
if err != nil {
417-
return nil, diag.FromErr(err)
417+
return nil, fromErr(err)
418418
}
419419

420420
switch resp.StatusCode() {
421421
case http.StatusOK:
422422
return resp.JSON200.Items, nil
423423
default:
424-
return nil, reportUnknownError(resp.StatusCode(), resp.Body)
424+
return nil, reportUnknownErrorFw(resp.StatusCode(), resp.Body)
425425
}
426426
}
427427

internal/fleet/integration/create.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package integration
2+
3+
import (
4+
"context"
5+
6+
"github.com/elastic/terraform-provider-elasticstack/internal/clients/fleet"
7+
"github.com/hashicorp/terraform-plugin-framework/resource"
8+
"github.com/hashicorp/terraform-plugin-framework/types"
9+
)
10+
11+
func (r *integrationResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
12+
var planModel integrationModel
13+
14+
diags := req.Plan.Get(ctx, &planModel)
15+
resp.Diagnostics.Append(diags...)
16+
if resp.Diagnostics.HasError() {
17+
return
18+
}
19+
20+
client, err := r.client.GetFleetClient()
21+
if err != nil {
22+
resp.Diagnostics.AddError(err.Error(), "")
23+
return
24+
}
25+
26+
name := planModel.Name.ValueString()
27+
version := planModel.Version.ValueString()
28+
force := planModel.Force.ValueBool()
29+
diags = fleet.InstallPackage(ctx, client, name, version, force)
30+
resp.Diagnostics.Append(diags...)
31+
if resp.Diagnostics.HasError() {
32+
return
33+
}
34+
35+
planModel.ID = types.StringValue(getPackageID(name, version))
36+
37+
diags = resp.State.Set(ctx, planModel)
38+
resp.Diagnostics.Append(diags...)
39+
}

internal/fleet/integration/delete.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package integration
2+
3+
import (
4+
"context"
5+
6+
"github.com/elastic/terraform-provider-elasticstack/internal/clients/fleet"
7+
"github.com/hashicorp/terraform-plugin-framework/resource"
8+
"github.com/hashicorp/terraform-plugin-log/tflog"
9+
)
10+
11+
func (r *integrationResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
12+
var stateModel integrationModel
13+
14+
diags := req.State.Get(ctx, &stateModel)
15+
resp.Diagnostics.Append(diags...)
16+
if resp.Diagnostics.HasError() {
17+
return
18+
}
19+
20+
client, err := r.client.GetFleetClient()
21+
if err != nil {
22+
resp.Diagnostics.AddError(err.Error(), "")
23+
return
24+
}
25+
26+
name := stateModel.Name.ValueString()
27+
version := stateModel.Version.ValueString()
28+
force := stateModel.Force.ValueBool()
29+
skipDestroy := stateModel.SkipDestroy.ValueBool()
30+
if skipDestroy {
31+
tflog.Debug(ctx, "Skipping uninstall of integration package", map[string]any{"name": name, "version": version})
32+
return
33+
}
34+
35+
diags = fleet.Uninstall(ctx, client, name, version, force)
36+
resp.Diagnostics.Append(diags...)
37+
}

internal/fleet/integration/models.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package integration
2+
3+
import (
4+
"github.com/elastic/terraform-provider-elasticstack/internal/utils"
5+
"github.com/hashicorp/terraform-plugin-framework/types"
6+
)
7+
8+
type integrationModel struct {
9+
ID types.String `tfsdk:"id"`
10+
Name types.String `tfsdk:"name"`
11+
Version types.String `tfsdk:"version"`
12+
Force types.Bool `tfsdk:"force"`
13+
SkipDestroy types.Bool `tfsdk:"skip_destroy"`
14+
}
15+
16+
func getPackageID(name string, version string) string {
17+
hash, _ := utils.StringToHash(name + version)
18+
return *hash
19+
}

internal/fleet/integration/read.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package integration
2+
3+
import (
4+
"context"
5+
6+
"github.com/elastic/terraform-provider-elasticstack/internal/clients/fleet"
7+
"github.com/hashicorp/terraform-plugin-framework/resource"
8+
"github.com/hashicorp/terraform-plugin-framework/types"
9+
)
10+
11+
func (r *integrationResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
12+
var stateModel integrationModel
13+
14+
diags := req.State.Get(ctx, &stateModel)
15+
resp.Diagnostics.Append(diags...)
16+
if resp.Diagnostics.HasError() {
17+
return
18+
}
19+
20+
client, err := r.client.GetFleetClient()
21+
if err != nil {
22+
resp.Diagnostics.AddError(err.Error(), "")
23+
return
24+
}
25+
26+
name := stateModel.Name.ValueString()
27+
version := stateModel.Version.ValueString()
28+
diags = fleet.ReadPackage(ctx, client, name, version)
29+
resp.Diagnostics.Append(diags...)
30+
if resp.Diagnostics.HasError() {
31+
resp.State.RemoveResource(ctx)
32+
return
33+
}
34+
35+
stateModel.ID = types.StringValue(getPackageID(name, version))
36+
37+
diags = resp.State.Set(ctx, stateModel)
38+
resp.Diagnostics.Append(diags...)
39+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package integration
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/elastic/terraform-provider-elasticstack/internal/clients"
8+
"github.com/hashicorp/terraform-plugin-framework/resource"
9+
)
10+
11+
var (
12+
_ resource.Resource = &integrationResource{}
13+
_ resource.ResourceWithConfigure = &integrationResource{}
14+
)
15+
16+
// NewResource is a helper function to simplify the provider implementation.
17+
func NewResource() resource.Resource {
18+
return &integrationResource{}
19+
}
20+
21+
type integrationResource struct {
22+
client *clients.ApiClient
23+
}
24+
25+
func (r *integrationResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
26+
client, diags := clients.ConvertProviderData(req.ProviderData)
27+
resp.Diagnostics.Append(diags...)
28+
r.client = client
29+
}
30+
31+
func (r *integrationResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
32+
resp.TypeName = fmt.Sprintf("%s_%s", req.ProviderTypeName, "fleet_integration")
33+
}
Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,52 @@
1-
package fleet_test
1+
package integration_test
22

33
import (
4+
"regexp"
45
"testing"
56

6-
"github.com/hashicorp/go-version"
7-
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
8-
97
"github.com/elastic/terraform-provider-elasticstack/internal/acctest"
108
"github.com/elastic/terraform-provider-elasticstack/internal/versionutils"
9+
"github.com/hashicorp/go-version"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
1111
)
1212

1313
var minVersionIntegration = version.Must(version.NewVersion("8.6.0"))
1414

15-
const integrationConfig = `
16-
provider "elasticstack" {
17-
elasticsearch {}
18-
kibana {}
19-
}
20-
21-
resource "elasticstack_fleet_integration" "test_integration" {
22-
name = "tcp"
23-
version = "1.16.0"
24-
force = true
25-
skip_destroy = true
26-
}
27-
`
28-
2915
func TestAccResourceIntegration(t *testing.T) {
3016
resource.Test(t, resource.TestCase{
3117
PreCheck: func() { acctest.PreCheck(t) },
3218
ProtoV6ProviderFactories: acctest.Providers,
3319
Steps: []resource.TestStep{
3420
{
3521
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minVersionIntegration),
36-
Config: integrationConfig,
22+
Config: testAccResourceIntegration,
3723
Check: resource.ComposeTestCheckFunc(
3824
resource.TestCheckResourceAttr("elasticstack_fleet_integration.test_integration", "name", "tcp"),
3925
resource.TestCheckResourceAttr("elasticstack_fleet_integration.test_integration", "version", "1.16.0"),
4026
),
4127
},
28+
{
29+
SkipFunc: versionutils.CheckIfVersionIsUnsupported(minVersionIntegration),
30+
ResourceName: "elasticstack_fleet_integration.test_integration",
31+
Config: testAccResourceIntegration,
32+
ImportState: true,
33+
ImportStateVerify: true,
34+
ExpectError: regexp.MustCompile("Resource Import Not Implemented"),
35+
},
4236
},
4337
})
4438
}
39+
40+
const testAccResourceIntegration = `
41+
provider "elasticstack" {
42+
elasticsearch {}
43+
kibana {}
44+
}
45+
46+
resource "elasticstack_fleet_integration" "test_integration" {
47+
name = "tcp"
48+
version = "1.16.0"
49+
force = true
50+
skip_destroy = true
51+
}
52+
`

internal/fleet/integration/schema.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package integration
2+
3+
import (
4+
"context"
5+
6+
"github.com/hashicorp/terraform-plugin-framework/resource"
7+
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
8+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
9+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
10+
)
11+
12+
func (r *integrationResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
13+
resp.Schema.Description = "Manage installation of a Fleet integration package."
14+
resp.Schema.Attributes = map[string]schema.Attribute{
15+
"id": schema.StringAttribute{
16+
Description: "The ID of this resource.",
17+
Computed: true,
18+
},
19+
"name": schema.StringAttribute{
20+
Description: "The integration package name.",
21+
Required: true,
22+
PlanModifiers: []planmodifier.String{
23+
stringplanmodifier.RequiresReplace(),
24+
},
25+
},
26+
"version": schema.StringAttribute{
27+
Description: "The integration package version.",
28+
Required: true,
29+
PlanModifiers: []planmodifier.String{
30+
stringplanmodifier.RequiresReplace(),
31+
},
32+
},
33+
"force": schema.BoolAttribute{
34+
Description: "Set to true to force the requested action.",
35+
Optional: true,
36+
},
37+
"skip_destroy": schema.BoolAttribute{
38+
Description: "Set to true if you do not wish the integration package to be uninstalled at destroy time, and instead just remove the integration package from the Terraform state.",
39+
Optional: true,
40+
},
41+
}
42+
}

0 commit comments

Comments
 (0)