Skip to content

Commit

Permalink
Fixup error handling during saved object imports (#738)
Browse files Browse the repository at this point in the history
* Fixup error handling during saved object imports

* Changelog

* Acceptance tests
  • Loading branch information
tobio authored Sep 3, 2024
1 parent 487195e commit b58a599
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Add support for data_stream `lifecycle` template settings ([#724](https://github.com/elastic/terraform-provider-elasticstack/pull/724))
- Fix a provider panic when `elasticstack_kibana_action_connector` reads a non-existant connector ([#729](https://github.com/elastic/terraform-provider-elasticstack/pull/729))
- Add support for `remote_indicies` to `elasticstack_elasticsearch_security_role` & `elasticstack_kibana_security_role` (#723)[https://github.com/elastic/terraform-provider-elasticstack/pull/723]
- Fix error handling in `elasticstack_kibana_import_saved_objects` ([#738](https://github.com/elastic/terraform-provider-elasticstack/pull/738))

## [0.11.6] - 2024-08-20

Expand Down
27 changes: 27 additions & 0 deletions internal/kibana/import_saved_objects/acc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ func TestAccResourceImportSavedObjects(t *testing.T) {
resource.TestCheckResourceAttr("elasticstack_kibana_import_saved_objects.settings", "errors.#", "0"),
),
},
{
// Ensure a partially successful import doesn't throw a provider error
Config: testAccResourceImportSavedObjectsMissingRef(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("elasticstack_kibana_import_saved_objects.settings", "success", "false"),
resource.TestCheckResourceAttr("elasticstack_kibana_import_saved_objects.settings", "success_count", "1"),
resource.TestCheckResourceAttr("elasticstack_kibana_import_saved_objects.settings", "success_results.#", "1"),
resource.TestCheckResourceAttr("elasticstack_kibana_import_saved_objects.settings", "errors.#", "1"),
),
},
},
})
}
Expand Down Expand Up @@ -67,3 +77,20 @@ EOT
}
`
}

func testAccResourceImportSavedObjectsMissingRef() string {
return `
provider "elasticstack" {
elasticsearch {}
kibana {}
}
resource "elasticstack_kibana_import_saved_objects" "settings" {
file_contents = <<-EOT
{"attributes":{"buildNum":42747,"defaultIndex":"metricbeat-*","theme:darkMode":true},"coreMigrationVersion":"7.0.0","id":"7.14.0","managed":false,"references":[],"type":"config","typeMigrationVersion":"7.0.0","updated_at":"2021-08-04T02:04:43.306Z","version":"WzY1MiwyXQ=="}
{"attributes":{"description":"","kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[{\"$state\":{\"store\":\"appState\"},\"meta\":{\"alias\":null,\"disabled\":false,\"key\":\"testName\",\"negate\":false,\"params\":{\"query\":\"perf-features\"},\"type\":\"phrase\",\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"query\":{\"match_phrase\":{\"testName\":\"perf-features\"}}},{\"$state\":{\"store\":\"appState\"},\"meta\":{\"alias\":null,\"disabled\":false,\"key\":\"status\",\"negate\":false,\"params\":{\"query\":\"failed\"},\"type\":\"phrase\",\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index\"},\"query\":{\"match_phrase\":{\"status\":\"failed\"}}},{\"$state\":{\"store\":\"appState\"},\"meta\":{\"alias\":null,\"disabled\":false,\"key\":\"targetEnvironment\",\"negate\":false,\"params\":{\"query\":\"dev\"},\"type\":\"phrase\",\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[2].meta.index\"},\"query\":{\"match_phrase\":{\"targetEnvironment\":\"dev\"}}}],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}"},"title":"healthchecks","uiStateJSON":"{}","version":1,"visState":"{\"title\":\"healthchecks\",\"type\":\"histogram\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"params\":{},\"schema\":\"metric\"},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"params\":{\"field\":\"@timestamp\",\"timeRange\":{\"from\":\"now/d\",\"to\":\"now/d\"},\"useNormalizedEsInterval\":true,\"scaleMetricValues\":false,\"interval\":\"30m\",\"drop_partials\":false,\"min_doc_count\":1,\"extended_bounds\":{}},\"schema\":\"segment\"},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"params\":{\"field\":\"testName\",\"orderBy\":\"1\",\"order\":\"desc\",\"size\":5,\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\"},\"schema\":\"group\"}],\"params\":{\"type\":\"histogram\",\"grid\":{\"categoryLines\":false},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"filter\":true,\"truncate\":100},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Count\"}}],\"seriesParams\":[{\"show\":true,\"type\":\"histogram\",\"mode\":\"normal\",\"data\":{\"label\":\"Count\",\"id\":\"1\"},\"valueAxis\":\"ValueAxis-1\",\"drawLinesBetweenPoints\":true,\"lineWidth\":2,\"showCircles\":true}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":true,\"labels\":{\"show\":false},\"thresholdLine\":{\"show\":false,\"value\":10,\"width\":1,\"style\":\"full\",\"color\":\"#E7664C\"},\"palette\":{\"type\":\"palette\",\"name\":\"kibana_palette\"},\"isVislibVis\":true,\"detailedTooltip\":true,\"legendSize\":\"auto\"}}"},"coreMigrationVersion":"8.8.0","id":"bacba650-0c8e-11eb-977b-cd2574857abe","managed":false,"references":[{"id":"5ba9aac0-0c7e-11ea-b151-954d48d0eae6","name":"kibanaSavedObjectMeta.searchSourceJSON.index","type":"index-pattern"},{"id":"5ba9aac0-0c7e-11ea-b151-954d48d0eae6","name":"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index","type":"index-pattern"},{"id":"5ba9aac0-0c7e-11ea-b151-954d48d0eae6","name":"kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index","type":"index-pattern"},{"id":"5ba9aac0-0c7e-11ea-b151-954d48d0eae6","name":"kibanaSavedObjectMeta.searchSourceJSON.filter[2].meta.index","type":"index-pattern"}],"type":"visualization","typeMigrationVersion":"8.5.0","updated_at":"2020-10-12T13:27:52.373Z","version":"WzE2NjgsMl0="}
{"excludedObjects":[],"excludedObjectsCount":0,"exportedCount":22,"missingRefCount":1,"missingReferences":[{"id":"5ba9aac0-0c7e-11ea-b151-954d48d0eae6","type":"index-pattern"}]}
EOT
overwrite = true
}`
}
41 changes: 34 additions & 7 deletions internal/kibana/import_saved_objects/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package import_saved_objects

import (
"context"
"fmt"
"strings"

"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-framework/diag"
Expand Down Expand Up @@ -71,7 +73,23 @@ func (r *Resource) importObjects(ctx context.Context, plan tfsdk.Plan, state *tf
}

if !respModel.Success && !model.IgnoreImportErrors.ValueBool() {
diags.AddError("not all objects were imported successfully", "see errors attribute for more details")
var detail strings.Builder
for i, err := range respModel.Errors {
detail.WriteString(fmt.Sprintf("import error [%d]: %s\n", i, err))
}
detail.WriteString("see the `errors` attribute for the full resposne")

if respModel.SuccessCount > 0 {
diags.AddWarning(
"not all objects were imported successfully",
detail.String(),
)
} else {
diags.AddError(
"no objects imported successfully",
detail.String(),
)
}
}
}

Expand All @@ -90,15 +108,24 @@ type importSuccess struct {
}

type importError struct {
ID string `json:"id"`
Type string `json:"type"`
Title string `json:"title"`
Error importErrorType `json:"error"`
Meta importMeta `json:"meta"`
ID string `tfsdk:"id" json:"id"`
Type string `tfsdk:"type" json:"type"`
Title string `tfsdk:"title" json:"title"`
Error importErrorType `tfsdk:"error" json:"error"`
Meta importMeta `tfsdk:"meta" json:"meta"`
}

func (ie importError) String() string {
title := ie.Title
if title == "" {
title = ie.Meta.Title
}

return fmt.Sprintf("[%s] error on [%s] with ID [%s] and title [%s]", ie.Error.Type, ie.Type, ie.ID, title)
}

type importErrorType struct {
Type string `json:"type"`
Type string `tfsdk:"type" json:"type"`
}

type importMeta struct {
Expand Down

0 comments on commit b58a599

Please sign in to comment.