From a5bed36a9011931fcf68d95090312a79acabe188 Mon Sep 17 00:00:00 2001 From: Raymond Lynch Date: Thu, 17 Oct 2024 11:13:32 -0400 Subject: [PATCH 1/8] fix epm --- generated/fleet/fleet.gen.go | 139 +++++++++++++++----- generated/fleet/getschema.go | 49 ++++++- internal/clients/fleet/fleet.go | 42 +++--- internal/fleet/integration/create.go | 4 +- internal/fleet/integration/read.go | 7 +- internal/fleet/integration/resource_test.go | 59 +++++++++ internal/fleet/integration/update.go | 2 +- 7 files changed, 237 insertions(+), 65 deletions(-) diff --git a/generated/fleet/fleet.gen.go b/generated/fleet/fleet.gen.go index 135643e8d..d602582fb 100644 --- a/generated/fleet/fleet.gen.go +++ b/generated/fleet/fleet.gen.go @@ -50,6 +50,27 @@ const ( Transform ElasticsearchAssetType = "transform" ) +// Defines values for GetPackageItemConditionsElasticsearchSubscription. +const ( + GetPackageItemConditionsElasticsearchSubscriptionBasic GetPackageItemConditionsElasticsearchSubscription = "basic" + GetPackageItemConditionsElasticsearchSubscriptionEnterprise GetPackageItemConditionsElasticsearchSubscription = "enterprise" + GetPackageItemConditionsElasticsearchSubscriptionGold GetPackageItemConditionsElasticsearchSubscription = "gold" + GetPackageItemConditionsElasticsearchSubscriptionPlatinum GetPackageItemConditionsElasticsearchSubscription = "platinum" +) + +// Defines values for GetPackageItemRelease. +const ( + GetPackageItemReleaseBeta GetPackageItemRelease = "beta" + GetPackageItemReleaseExperimental GetPackageItemRelease = "experimental" + GetPackageItemReleaseGa GetPackageItemRelease = "ga" +) + +// Defines values for GetPackageItemSourceLicense. +const ( + GetPackageItemSourceLicenseApache20 GetPackageItemSourceLicense = "Apache-2.0" + GetPackageItemSourceLicenseElastic20 GetPackageItemSourceLicense = "Elastic-2.0" +) + // Defines values for KibanaSavedObjectType. const ( CspRuleTemplate KibanaSavedObjectType = "csp_rule_template" @@ -123,23 +144,23 @@ const ( // Defines values for PackageInfoConditionsElasticsearchSubscription. const ( - Basic PackageInfoConditionsElasticsearchSubscription = "basic" - Enterprise PackageInfoConditionsElasticsearchSubscription = "enterprise" - Gold PackageInfoConditionsElasticsearchSubscription = "gold" - Platinum PackageInfoConditionsElasticsearchSubscription = "platinum" + PackageInfoConditionsElasticsearchSubscriptionBasic PackageInfoConditionsElasticsearchSubscription = "basic" + PackageInfoConditionsElasticsearchSubscriptionEnterprise PackageInfoConditionsElasticsearchSubscription = "enterprise" + PackageInfoConditionsElasticsearchSubscriptionGold PackageInfoConditionsElasticsearchSubscription = "gold" + PackageInfoConditionsElasticsearchSubscriptionPlatinum PackageInfoConditionsElasticsearchSubscription = "platinum" ) // Defines values for PackageInfoRelease. const ( - Beta PackageInfoRelease = "beta" - Experimental PackageInfoRelease = "experimental" - Ga PackageInfoRelease = "ga" + PackageInfoReleaseBeta PackageInfoRelease = "beta" + PackageInfoReleaseExperimental PackageInfoRelease = "experimental" + PackageInfoReleaseGa PackageInfoRelease = "ga" ) // Defines values for PackageInfoSourceLicense. const ( - Apache20 PackageInfoSourceLicense = "Apache-2.0" - Elastic20 PackageInfoSourceLicense = "Elastic-2.0" + PackageInfoSourceLicenseApache20 PackageInfoSourceLicense = "Apache-2.0" + PackageInfoSourceLicenseElastic20 PackageInfoSourceLicense = "Elastic-2.0" ) // Defines values for PackageInstallSource. @@ -281,6 +302,76 @@ type FleetServerHost struct { Name *string `json:"name,omitempty"` } +// GetPackageItem defines model for get_package_item. +type GetPackageItem struct { + Categories []string `json:"categories"` + Conditions struct { + Elasticsearch *struct { + Subscription *GetPackageItemConditionsElasticsearchSubscription `json:"subscription,omitempty"` + } `json:"elasticsearch,omitempty"` + Kibana *struct { + Versions *string `json:"versions,omitempty"` + } `json:"kibana,omitempty"` + } `json:"conditions"` + DataStreams *[]struct { + IngesetPipeline string `json:"ingeset_pipeline"` + Name string `json:"name"` + Package string `json:"package"` + Release string `json:"release"` + Title string `json:"title"` + Type string `json:"type"` + Vars *[]struct { + Default string `json:"default"` + Name string `json:"name"` + } `json:"vars,omitempty"` + } `json:"data_streams,omitempty"` + Description string `json:"description"` + Download string `json:"download"` + Elasticsearch *struct { + Privileges *struct { + Cluster *[]string `json:"cluster,omitempty"` + } `json:"privileges,omitempty"` + } `json:"elasticsearch,omitempty"` + FormatVersion string `json:"format_version"` + Internal *bool `json:"internal,omitempty"` + KeepPoliciesUpToDate *bool `json:"keepPoliciesUpToDate,omitempty"` + LatestVersion *string `json:"latestVersion,omitempty"` + LicensePath *string `json:"licensePath,omitempty"` + Name string `json:"name"` + Notice *string `json:"notice,omitempty"` + Path string `json:"path"` + Readme *string `json:"readme,omitempty"` + + // Release release label is deprecated, derive from the version instead (packages follow semver) + // Deprecated: + Release *GetPackageItemRelease `json:"release,omitempty"` + // Deprecated: + SavedObject map[string]interface{} `json:"savedObject"` + Screenshots *[]struct { + Path string `json:"path"` + Size *string `json:"size,omitempty"` + Src string `json:"src"` + Title *string `json:"title,omitempty"` + Type *string `json:"type,omitempty"` + } `json:"screenshots,omitempty"` + Source *struct { + License *GetPackageItemSourceLicense `json:"license,omitempty"` + } `json:"source,omitempty"` + Status PackageStatus `json:"status"` + Title string `json:"title"` + Type string `json:"type"` + Version string `json:"version"` +} + +// GetPackageItemConditionsElasticsearchSubscription defines model for GetPackageItem.Conditions.Elasticsearch.Subscription. +type GetPackageItemConditionsElasticsearchSubscription string + +// GetPackageItemRelease release label is deprecated, derive from the version instead (packages follow semver) +type GetPackageItemRelease string + +// GetPackageItemSourceLicense defines model for GetPackageItem.Source.License. +type GetPackageItemSourceLicense string + // GetPackagesResponse defines model for get_packages_response. type GetPackagesResponse struct { Items []SearchResult `json:"items"` @@ -592,7 +683,6 @@ type OutputUpdateRequestLogstashType string // PackageInfo defines model for package_info. type PackageInfo struct { - Assets []string `json:"assets"` Categories []string `json:"categories"` Conditions struct { Elasticsearch *struct { @@ -621,12 +711,11 @@ type PackageInfo struct { Cluster *[]string `json:"cluster,omitempty"` } `json:"privileges,omitempty"` } `json:"elasticsearch,omitempty"` - FormatVersion string `json:"format_version"` - Icons *[]string `json:"icons,omitempty"` - Internal *bool `json:"internal,omitempty"` - Name string `json:"name"` - Path string `json:"path"` - Readme *string `json:"readme,omitempty"` + FormatVersion string `json:"format_version"` + Internal *bool `json:"internal,omitempty"` + Name string `json:"name"` + Path string `json:"path"` + Readme *string `json:"readme,omitempty"` // Release release label is deprecated, derive from the version instead (packages follow semver) // Deprecated: @@ -3393,14 +3482,7 @@ type GetPackageResponse struct { Body []byte HTTPResponse *http.Response JSON200 *struct { - Item *PackageInfo `json:"item,omitempty"` - KeepPoliciesUpToDate *bool `json:"keepPoliciesUpToDate,omitempty"` - LatestVersion *string `json:"latestVersion,omitempty"` - LicensePath *string `json:"licensePath,omitempty"` - Notice *string `json:"notice,omitempty"` - // Deprecated: - SavedObject map[string]interface{} `json:"savedObject"` - Status PackageStatus `json:"status"` + Item *GetPackageItem `json:"item,omitempty"` } JSON400 *Error } @@ -4344,14 +4426,7 @@ func ParseGetPackageResponse(rsp *http.Response) (*GetPackageResponse, error) { switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: var dest struct { - Item *PackageInfo `json:"item,omitempty"` - KeepPoliciesUpToDate *bool `json:"keepPoliciesUpToDate,omitempty"` - LatestVersion *string `json:"latestVersion,omitempty"` - LicensePath *string `json:"licensePath,omitempty"` - Notice *string `json:"notice,omitempty"` - // Deprecated: - SavedObject map[string]interface{} `json:"savedObject"` - Status PackageStatus `json:"status"` + Item *GetPackageItem `json:"item,omitempty"` } if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err diff --git a/generated/fleet/getschema.go b/generated/fleet/getschema.go index b08753c35..548d9cd14 100644 --- a/generated/fleet/getschema.go +++ b/generated/fleet/getschema.go @@ -73,6 +73,7 @@ var transformers = []TransformFunc{ transformAddPackagePolicyVars, transformAddPackagePolicySecretReferences, transformFixPackageSearchResult, + transformFixGetPackageResult, } // transformFilterPaths filters the paths in a schema down to @@ -232,16 +233,36 @@ func transformInlinePackageDefinitions(schema *Schema) { // Get { - props, ok := epmPath.Get.Responses.GetFields("200.content.application/json.schema.allOf.1.properties") + respSchema, ok := epmPath.Get.Responses.GetFields("200.content.application/json.schema") if !ok { panic("properties not found") } - // status needs to be moved to schemes and a ref inserted in its place. - value, _ := props.Get("status") + // allOf.1 should also be inside "item" + _allOf, _ := respSchema.Get("allOf") + allOf := _allOf.([]any) + respSchema.Delete("allOf") + + list := make([]any, 2) + allOf0, _ := Fields(allOf[0].(map[string]any)).GetFields("properties.item") + allOf1 := Fields(allOf[1].(map[string]any)) + list[0] = allOf0 + list[1] = allOf1 + respSchema.Set("properties.item.allOf", list) + + // item needs to be moved to schemas and a ref inserted in its place. + value, _ := respSchema.Get("properties.item.allOf") + respSchema.Delete("properties.item.allOf") + schema.Components.Set("schemas.get_package_item.allOf", value) + respSchema.Set("properties.item.$ref", "#/components/schemas/get_package_item") + + // status needs to be moved to schemas and a ref inserted in its place. + props, _ := schema.Components.GetFields("schemas.get_package_item.allOf.1.properties") + value, _ = props.GetFields("status") schema.Components.Set("schemas.package_status", value) props.Delete("status") props.Set("status.$ref", "#/components/schemas/package_status") + } // Post @@ -369,6 +390,18 @@ func transformFixPackageSearchResult(schema *Schema) { properties.Delete("installationInfo") } +// transformFixGetPackageResult removes unneeded fields from the +// GetPackageResult struct. These fields are also causing parsing errors. +func transformFixGetPackageResult(schema *Schema) { + properties, ok := schema.Components.GetFields("schemas.package_info.properties") + if !ok { + panic("properties not found") + } + properties.Delete("assets") + properties.Delete("icons") + properties.Delete("installationInfo") +} + // downloadFile will download a file from url and return the // bytes. If the request fails, or a non 200 error code is // observed in the response, an error is returned instead. @@ -462,11 +495,15 @@ func (f Fields) Get(key string) (any, bool) { if !ok { return nil, false } - if m, isMap := slicedValue.(map[string]any); ok && isMap { + + switch m := slicedValue.(type) { + case map[string]any: return Fields(m).Get(postSliceKeys) + case Fields: + return m.Get(postSliceKeys) + default: + return slicedValue, true } - return slicedValue, true - default: rootKey = key } diff --git a/internal/clients/fleet/fleet.go b/internal/clients/fleet/fleet.go index 1a0905ceb..4ec16b0e6 100644 --- a/internal/clients/fleet/fleet.go +++ b/internal/clients/fleet/fleet.go @@ -4,8 +4,8 @@ import ( "context" "errors" "fmt" - "io" "net/http" + "strings" fleetapi "github.com/elastic/terraform-provider-elasticstack/generated/fleet" "github.com/elastic/terraform-provider-elasticstack/internal/utils" @@ -333,27 +333,21 @@ func DeletePackagePolicy(ctx context.Context, client *Client, id string, force b } // ReadPackage reads a specific package from the API. -func ReadPackage(ctx context.Context, client *Client, name, version string) diag.Diagnostics { +func ReadPackage(ctx context.Context, client *Client, name, version string) (*fleetapi.GetPackageItem, diag.Diagnostics) { params := fleetapi.GetPackageParams{} - resp, err := client.API.GetPackage(ctx, name, version, ¶ms) + resp, err := client.API.GetPackageWithResponse(ctx, name, version, ¶ms) if err != nil { - return utils.FrameworkDiagFromError(err) + return nil, utils.FrameworkDiagFromError(err) } - defer resp.Body.Close() - switch resp.StatusCode { + switch resp.StatusCode() { case http.StatusOK: - return nil + return resp.JSON200.Item, nil case http.StatusNotFound: - return utils.FrameworkDiagFromError(ErrPackageNotFound) + return nil, utils.FrameworkDiagFromError(ErrPackageNotFound) default: - errData, err := io.ReadAll(resp.Body) - if err != nil { - return utils.FrameworkDiagFromError(err) - } - - return reportUnknownError(resp.StatusCode, errData) + return nil, reportUnknownError(resp.StatusCode(), resp.Body) } } @@ -365,22 +359,16 @@ func InstallPackage(ctx context.Context, client *Client, name, version string, f IgnoreConstraints: nil, } - resp, err := client.API.InstallPackage(ctx, name, version, ¶ms, body) + resp, err := client.API.InstallPackageWithResponse(ctx, name, version, ¶ms, body) if err != nil { return utils.FrameworkDiagFromError(err) } - defer resp.Body.Close() - switch resp.StatusCode { + switch resp.StatusCode() { case http.StatusOK: return nil default: - errData, err := io.ReadAll(resp.Body) - if err != nil { - return utils.FrameworkDiagFromError(err) - } - - return reportUnknownError(resp.StatusCode, errData) + return reportUnknownError(resp.StatusCode(), resp.Body) } } @@ -399,6 +387,14 @@ func Uninstall(ctx context.Context, client *Client, name, version string, force switch resp.StatusCode() { case http.StatusOK: return nil + case http.StatusBadRequest: + msg := resp.JSON400.Message + // {"statusCode":400,"error":"Bad Request","message":"some-integration is not installed"} + if msg != nil && strings.Contains(*msg, "is not installed") { + return nil + } else { + return reportUnknownError(resp.StatusCode(), resp.Body) + } case http.StatusNotFound: return nil default: diff --git a/internal/fleet/integration/create.go b/internal/fleet/integration/create.go index e166cf45c..68869cab9 100644 --- a/internal/fleet/integration/create.go +++ b/internal/fleet/integration/create.go @@ -11,10 +11,10 @@ import ( ) func (r *integrationResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - r.create(ctx, req.Plan, &resp.State, resp.Diagnostics) + r.create(ctx, req.Plan, &resp.State, &resp.Diagnostics) } -func (r integrationResource) create(ctx context.Context, plan tfsdk.Plan, state *tfsdk.State, respDiags diag.Diagnostics) { +func (r integrationResource) create(ctx context.Context, plan tfsdk.Plan, state *tfsdk.State, respDiags *diag.Diagnostics) { var planModel integrationModel diags := plan.Get(ctx, &planModel) diff --git a/internal/fleet/integration/read.go b/internal/fleet/integration/read.go index fbd345851..96b759c04 100644 --- a/internal/fleet/integration/read.go +++ b/internal/fleet/integration/read.go @@ -3,6 +3,7 @@ package integration import ( "context" + fleetapi "github.com/elastic/terraform-provider-elasticstack/generated/fleet" "github.com/elastic/terraform-provider-elasticstack/internal/clients/fleet" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/types" @@ -25,12 +26,16 @@ func (r *integrationResource) Read(ctx context.Context, req resource.ReadRequest name := stateModel.Name.ValueString() version := stateModel.Version.ValueString() - diags = fleet.ReadPackage(ctx, client, name, version) + pkg, diags := fleet.ReadPackage(ctx, client, name, version) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { resp.State.RemoveResource(ctx) return } + if pkg.Status != fleetapi.Installed { + resp.State.RemoveResource(ctx) + return + } stateModel.ID = types.StringValue(getPackageID(name, version)) diff --git a/internal/fleet/integration/resource_test.go b/internal/fleet/integration/resource_test.go index 87826e7b8..5a95af07c 100644 --- a/internal/fleet/integration/resource_test.go +++ b/internal/fleet/integration/resource_test.go @@ -1,10 +1,14 @@ package integration_test import ( + "context" "regexp" "testing" "github.com/elastic/terraform-provider-elasticstack/internal/acctest" + "github.com/elastic/terraform-provider-elasticstack/internal/clients" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/fleet" + "github.com/elastic/terraform-provider-elasticstack/internal/utils" "github.com/elastic/terraform-provider-elasticstack/internal/versionutils" "github.com/hashicorp/go-version" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -68,6 +72,47 @@ func TestAccResourceIntegration(t *testing.T) { }) } +func TestAccResourceIntegrationDeleted(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ProtoV6ProviderFactories: acctest.Providers, + Steps: []resource.TestStep{ + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minVersionIntegration), + Config: testAccResourceIntegrationDeleted, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_fleet_integration.test_integration", "name", "sysmon_linux"), + resource.TestCheckResourceAttr("elasticstack_fleet_integration.test_integration", "version", "1.7.0"), + ), + }, + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minVersionIntegration), + Config: testAccResourceIntegrationDeleted, + // Force uninstall the integration + PreConfig: func() { + client, err := clients.NewAcceptanceTestingClient() + if err != nil { + panic(err) + } + fleetClient, err := client.GetFleetClient() + if err != nil { + panic(err) + } + + ctx := context.Background() + diags := fleet.Uninstall(ctx, fleetClient, "sysmon_linux", "1.7.0", true) + if diags.HasError() { + panic(utils.FwDiagsAsError(diags)) + } + }, + // Expect the plan to want to reinstall + PlanOnly: true, + ExpectNonEmptyPlan: true, + }, + }, + }) +} + const testAccResourceIntegration = ` provider "elasticstack" { elasticsearch {} @@ -81,3 +126,17 @@ resource "elasticstack_fleet_integration" "test_integration" { skip_destroy = true } ` + +const testAccResourceIntegrationDeleted = ` +provider "elasticstack" { + elasticsearch {} + kibana {} +} + +resource "elasticstack_fleet_integration" "test_integration" { + name = "sysmon_linux" + version = "1.7.0" + force = true + skip_destroy = false +} +` diff --git a/internal/fleet/integration/update.go b/internal/fleet/integration/update.go index 7e4bc9405..28e98b1ce 100644 --- a/internal/fleet/integration/update.go +++ b/internal/fleet/integration/update.go @@ -7,5 +7,5 @@ import ( ) func (r *integrationResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - r.create(ctx, req.Plan, &resp.State, resp.Diagnostics) + r.create(ctx, req.Plan, &resp.State, &resp.Diagnostics) } From adb605454b27cb0f0da4f2cedead09b44c52cb41 Mon Sep 17 00:00:00 2001 From: Raymond Lynch Date: Thu, 17 Oct 2024 11:24:11 -0400 Subject: [PATCH 2/8] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d188307bd..92f63ee5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - Support updating `elasticstack_elasticsearch_security_api_key` when supported by the backing cluster ([#843](https://github.com/elastic/terraform-provider-elasticstack/pull/843)) - Fix validation of `throttle`, and `interval` attributes in `elasticstack_kibana_alerting_rule` allowing all Elastic duration values ([#846](https://github.com/elastic/terraform-provider-elasticstack/pull/846)) - Fix boolean setting parsing for `elasticstack_elasticsearch_indices` data source. ([#842](https://github.com/elastic/terraform-provider-elasticstack/pull/842)) +- Fix handling of EPM packages when uninstalled outside Terraform, and diags in create/update. ([#854](https://github.com/elastic/terraform-provider-elasticstack/pull/854)) ## [0.11.9] - 2024-10-14 From 5353265d75c2da9f98a14b8083be98f1c05f3ef7 Mon Sep 17 00:00:00 2001 From: Raymond Date: Mon, 21 Oct 2024 19:40:24 -0400 Subject: [PATCH 3/8] Update internal/fleet/integration/resource_test.go Co-authored-by: Toby Brain --- internal/fleet/integration/resource_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/fleet/integration/resource_test.go b/internal/fleet/integration/resource_test.go index 5a95af07c..22f05622e 100644 --- a/internal/fleet/integration/resource_test.go +++ b/internal/fleet/integration/resource_test.go @@ -91,9 +91,7 @@ func TestAccResourceIntegrationDeleted(t *testing.T) { // Force uninstall the integration PreConfig: func() { client, err := clients.NewAcceptanceTestingClient() - if err != nil { - panic(err) - } + require.NoError(t, err) fleetClient, err := client.GetFleetClient() if err != nil { panic(err) From adfec1107c49c1d32f3a1e2947a4daeb1a214509 Mon Sep 17 00:00:00 2001 From: Raymond Date: Mon, 21 Oct 2024 19:40:36 -0400 Subject: [PATCH 4/8] Update internal/fleet/integration/resource_test.go Co-authored-by: Toby Brain --- internal/fleet/integration/resource_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/fleet/integration/resource_test.go b/internal/fleet/integration/resource_test.go index 22f05622e..e7e509a85 100644 --- a/internal/fleet/integration/resource_test.go +++ b/internal/fleet/integration/resource_test.go @@ -93,9 +93,7 @@ func TestAccResourceIntegrationDeleted(t *testing.T) { client, err := clients.NewAcceptanceTestingClient() require.NoError(t, err) fleetClient, err := client.GetFleetClient() - if err != nil { - panic(err) - } + require.NoError(t, err) ctx := context.Background() diags := fleet.Uninstall(ctx, fleetClient, "sysmon_linux", "1.7.0", true) From e00bddf7835c999f0f525f5138f1d03941751f43 Mon Sep 17 00:00:00 2001 From: Raymond Date: Mon, 21 Oct 2024 19:40:41 -0400 Subject: [PATCH 5/8] Update internal/fleet/integration/resource_test.go Co-authored-by: Toby Brain --- internal/fleet/integration/resource_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/fleet/integration/resource_test.go b/internal/fleet/integration/resource_test.go index e7e509a85..52e44140e 100644 --- a/internal/fleet/integration/resource_test.go +++ b/internal/fleet/integration/resource_test.go @@ -97,9 +97,7 @@ func TestAccResourceIntegrationDeleted(t *testing.T) { ctx := context.Background() diags := fleet.Uninstall(ctx, fleetClient, "sysmon_linux", "1.7.0", true) - if diags.HasError() { - panic(utils.FwDiagsAsError(diags)) - } + require.Empty(t, diags) }, // Expect the plan to want to reinstall PlanOnly: true, From 75c5b2ce6a6e4e28b0b823b3f4d15b4361cd8e35 Mon Sep 17 00:00:00 2001 From: Raymond Date: Mon, 21 Oct 2024 19:48:40 -0400 Subject: [PATCH 6/8] Update internal/clients/fleet/fleet.go Co-authored-by: Toby Brain --- internal/clients/fleet/fleet.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/clients/fleet/fleet.go b/internal/clients/fleet/fleet.go index 4ec16b0e6..b104c4ed1 100644 --- a/internal/clients/fleet/fleet.go +++ b/internal/clients/fleet/fleet.go @@ -390,7 +390,7 @@ func Uninstall(ctx context.Context, client *Client, name, version string, force case http.StatusBadRequest: msg := resp.JSON400.Message // {"statusCode":400,"error":"Bad Request","message":"some-integration is not installed"} - if msg != nil && strings.Contains(*msg, "is not installed") { + if msg != nil && *msg == fmt.Sprintf("%s is not installed", name) { return nil } else { return reportUnknownError(resp.StatusCode(), resp.Body) From 96ef7052647aa51eeed0ae7e999c557359d0d18f Mon Sep 17 00:00:00 2001 From: Raymond Lynch Date: Mon, 21 Oct 2024 19:49:18 -0400 Subject: [PATCH 7/8] import and formatting --- internal/clients/fleet/fleet.go | 1 - internal/fleet/integration/resource_test.go | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/clients/fleet/fleet.go b/internal/clients/fleet/fleet.go index b104c4ed1..393b2f9b4 100644 --- a/internal/clients/fleet/fleet.go +++ b/internal/clients/fleet/fleet.go @@ -389,7 +389,6 @@ func Uninstall(ctx context.Context, client *Client, name, version string, force return nil case http.StatusBadRequest: msg := resp.JSON400.Message - // {"statusCode":400,"error":"Bad Request","message":"some-integration is not installed"} if msg != nil && *msg == fmt.Sprintf("%s is not installed", name) { return nil } else { diff --git a/internal/fleet/integration/resource_test.go b/internal/fleet/integration/resource_test.go index 52e44140e..a2d540743 100644 --- a/internal/fleet/integration/resource_test.go +++ b/internal/fleet/integration/resource_test.go @@ -8,10 +8,10 @@ import ( "github.com/elastic/terraform-provider-elasticstack/internal/acctest" "github.com/elastic/terraform-provider-elasticstack/internal/clients" "github.com/elastic/terraform-provider-elasticstack/internal/clients/fleet" - "github.com/elastic/terraform-provider-elasticstack/internal/utils" "github.com/elastic/terraform-provider-elasticstack/internal/versionutils" "github.com/hashicorp/go-version" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/stretchr/testify/require" ) var minVersionIntegration = version.Must(version.NewVersion("8.6.0")) @@ -92,6 +92,7 @@ func TestAccResourceIntegrationDeleted(t *testing.T) { PreConfig: func() { client, err := clients.NewAcceptanceTestingClient() require.NoError(t, err) + fleetClient, err := client.GetFleetClient() require.NoError(t, err) From 5bfde4bfe0d7d4b61faf9ae20d4bcf81b3105fd7 Mon Sep 17 00:00:00 2001 From: Raymond Lynch Date: Mon, 21 Oct 2024 19:58:24 -0400 Subject: [PATCH 8/8] i should really fmt locally first --- internal/clients/fleet/fleet.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/clients/fleet/fleet.go b/internal/clients/fleet/fleet.go index 393b2f9b4..2ce1230a2 100644 --- a/internal/clients/fleet/fleet.go +++ b/internal/clients/fleet/fleet.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "net/http" - "strings" fleetapi "github.com/elastic/terraform-provider-elasticstack/generated/fleet" "github.com/elastic/terraform-provider-elasticstack/internal/utils"