Skip to content

Commit e136626

Browse files
committed
impl fw resource/data_source integration
1 parent dd89f3c commit e136626

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
@@ -325,32 +325,32 @@ func DeletePackagePolicy(ctx context.Context, client *Client, id string, force b
325325
}
326326

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

331331
resp, err := client.API.GetPackage(ctx, name, version, &params)
332332
if err != nil {
333-
return diag.FromErr(err)
333+
return fromErr(err)
334334
}
335335
defer resp.Body.Close()
336336

337337
switch resp.StatusCode {
338338
case http.StatusOK:
339339
return nil
340340
case http.StatusNotFound:
341-
return diag.FromErr(ErrPackageNotFound)
341+
return fromErr(ErrPackageNotFound)
342342
default:
343343
errData, err := io.ReadAll(resp.Body)
344344
if err != nil {
345-
return diag.FromErr(err)
345+
return fromErr(err)
346346
}
347347

348-
return reportUnknownError(resp.StatusCode, errData)
348+
return reportUnknownErrorFw(resp.StatusCode, errData)
349349
}
350350
}
351351

352352
// InstallPackage installs a package.
353-
func InstallPackage(ctx context.Context, client *Client, name, version string, force bool) diag.Diagnostics {
353+
func InstallPackage(ctx context.Context, client *Client, name, version string, force bool) fwdiag.Diagnostics {
354354
params := fleetapi.InstallPackageParams{}
355355
body := fleetapi.InstallPackageJSONRequestBody{
356356
Force: &force,
@@ -359,7 +359,7 @@ func InstallPackage(ctx context.Context, client *Client, name, version string, f
359359

360360
resp, err := client.API.InstallPackage(ctx, name, version, &params, body)
361361
if err != nil {
362-
return diag.FromErr(err)
362+
return fromErr(err)
363363
}
364364
defer resp.Body.Close()
365365

@@ -369,23 +369,23 @@ func InstallPackage(ctx context.Context, client *Client, name, version string, f
369369
default:
370370
errData, err := io.ReadAll(resp.Body)
371371
if err != nil {
372-
return diag.FromErr(err)
372+
return fromErr(err)
373373
}
374374

375-
return reportUnknownError(resp.StatusCode, errData)
375+
return reportUnknownErrorFw(resp.StatusCode, errData)
376376
}
377377
}
378378

379379
// Uninstall uninstalls a package.
380-
func Uninstall(ctx context.Context, client *Client, name, version string, force bool) diag.Diagnostics {
380+
func Uninstall(ctx context.Context, client *Client, name, version string, force bool) fwdiag.Diagnostics {
381381
params := fleetapi.DeletePackageParams{}
382382
body := fleetapi.DeletePackageJSONRequestBody{
383383
Force: &force,
384384
}
385385

386386
resp, err := client.API.DeletePackageWithResponse(ctx, name, version, &params, body)
387387
if err != nil {
388-
return diag.FromErr(err)
388+
return fromErr(err)
389389
}
390390

391391
switch resp.StatusCode() {
@@ -394,26 +394,26 @@ func Uninstall(ctx context.Context, client *Client, name, version string, force
394394
case http.StatusNotFound:
395395
return nil
396396
default:
397-
return reportUnknownError(resp.StatusCode(), resp.Body)
397+
return reportUnknownErrorFw(resp.StatusCode(), resp.Body)
398398
}
399399
}
400400

401401
// AllPackages returns information about the latest packages known to Fleet.
402-
func AllPackages(ctx context.Context, client *Client, prerelease bool) ([]fleetapi.SearchResult, diag.Diagnostics) {
402+
func AllPackages(ctx context.Context, client *Client, prerelease bool) ([]fleetapi.SearchResult, fwdiag.Diagnostics) {
403403
params := fleetapi.ListAllPackagesParams{
404404
Prerelease: &prerelease,
405405
}
406406

407407
resp, err := client.API.ListAllPackagesWithResponse(ctx, &params)
408408
if err != nil {
409-
return nil, diag.FromErr(err)
409+
return nil, fromErr(err)
410410
}
411411

412412
switch resp.StatusCode() {
413413
case http.StatusOK:
414414
return resp.JSON200.Items, nil
415415
default:
416-
return nil, reportUnknownError(resp.StatusCode(), resp.Body)
416+
return nil, reportUnknownErrorFw(resp.StatusCode(), resp.Body)
417417
}
418418
}
419419

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)