diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9d4dc2113..c781f0cc3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -87,8 +87,7 @@ jobs: fail-fast: false matrix: version: - - '7.16.3' - - '7.17.4' + - '7.17.13' - '8.0.1' - '8.1.3' - '8.2.3' @@ -96,9 +95,10 @@ jobs: - '8.4.3' - '8.5.3' - '8.6.2' - - '8.7.0' + - '8.7.1' - '8.8.2' - '8.9.2' + - '8.10.2' steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v4 diff --git a/Makefile b/Makefile index fad095da7..810222dfa 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ ACCTEST_COUNT = 1 TEST ?= ./... SWAGGER_VERSION ?= 8.7 -GOVERSION ?= 1.19 +GOVERSION ?= 1.20 STACK_VERSION ?= 8.9.0 diff --git a/go.mod b/go.mod index dc1d26366..b4227fa60 100644 --- a/go.mod +++ b/go.mod @@ -6,14 +6,16 @@ require ( github.com/deepmap/oapi-codegen v1.14.0 github.com/disaster37/go-kibana-rest/v8 v8.5.0 github.com/elastic/go-elasticsearch/v7 v7.17.10 + github.com/google/uuid v1.3.1 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/go-version v1.6.0 - github.com/hashicorp/terraform-plugin-framework v1.4.0 + github.com/hashicorp/terraform-plugin-framework v1.4.1 github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 github.com/hashicorp/terraform-plugin-go v0.19.0 github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/hashicorp/terraform-plugin-mux v0.12.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0 + github.com/mitchellh/mapstructure v1.5.0 github.com/oapi-codegen/runtime v1.0.0 github.com/stretchr/testify v1.8.4 ) @@ -30,7 +32,6 @@ require ( github.com/go-test/deep v1.0.8 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/go-cmp v0.5.9 // indirect - github.com/google/uuid v1.3.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -52,7 +53,6 @@ require ( github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/oklog/run v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/go.sum b/go.sum index 9fb62bb31..94947234a 100644 --- a/go.sum +++ b/go.sum @@ -80,12 +80,8 @@ github.com/hashicorp/terraform-exec v0.19.0 h1:FpqZ6n50Tk95mItTSS9BjeOVUb4eg81Sp github.com/hashicorp/terraform-exec v0.19.0/go.mod h1:tbxUpe3JKruE9Cuf65mycSIT8KiNPZ0FkuTE3H4urQg= github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQHgyRwf3RkyA= github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o= -github.com/hashicorp/terraform-plugin-framework v1.2.0 h1:MZjFFfULnFq8fh04FqrKPcJ/nGpHOvX4buIygT3MSNY= -github.com/hashicorp/terraform-plugin-framework v1.2.0/go.mod h1:nToI62JylqXDq84weLJ/U3umUsBhZAaTmU0HXIVUOcw= -github.com/hashicorp/terraform-plugin-framework v1.4.0 h1:WKbtCRtNrjsh10eA7NZvC/Qyr7zp77j+D21aDO5th9c= -github.com/hashicorp/terraform-plugin-framework v1.4.0/go.mod h1:XC0hPcQbBvlbxwmjxuV/8sn8SbZRg4XwGMs22f+kqV0= -github.com/hashicorp/terraform-plugin-framework-validators v0.10.0 h1:4L0tmy/8esP6OcvocVymw52lY0HyQ5OxB7VNl7k4bS0= -github.com/hashicorp/terraform-plugin-framework-validators v0.10.0/go.mod h1:qdQJCdimB9JeX2YwOpItEu+IrfoJjWQ5PhLpAOMDQAE= +github.com/hashicorp/terraform-plugin-framework v1.4.1 h1:ZC29MoB3Nbov6axHdgPbMz7799pT5H8kIrM8YAsaVrs= +github.com/hashicorp/terraform-plugin-framework v1.4.1/go.mod h1:XC0hPcQbBvlbxwmjxuV/8sn8SbZRg4XwGMs22f+kqV0= github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 h1:HOjBuMbOEzl7snOdOoUfE2Jgeto6JOjLVQ39Ls2nksc= github.com/hashicorp/terraform-plugin-framework-validators v0.12.0/go.mod h1:jfHGE/gzjxYz6XoUwi/aYiiKrJDeutQNUtGQXkaHklg= github.com/hashicorp/terraform-plugin-go v0.19.0 h1:BuZx/6Cp+lkmiG0cOBk6Zps0Cb2tmqQpDM3iAtnhDQU= diff --git a/internal/kibana/space.go b/internal/kibana/space.go index 908e3e213..a095c6238 100644 --- a/internal/kibana/space.go +++ b/internal/kibana/space.go @@ -121,12 +121,7 @@ func resourceSpaceUpsert(ctx context.Context, d *schema.ResourceData, meta inter } } - id, diags := client.ID(ctx, spaceResponse.ID) - if diags.HasError() { - return diags - } - - d.SetId(id.String()) + d.SetId(spaceResponse.ID) return resourceSpaceRead(ctx, d, meta) } @@ -136,11 +131,10 @@ func resourceSpaceRead(ctx context.Context, d *schema.ResourceData, meta interfa if diags.HasError() { return diags } - compId, diags := clients.CompositeIdFromStr(d.Id()) - if diags.HasError() { - return diags + id := d.Id() + if compId, diags := clients.CompositeIdFromStr(id); diags == nil { + id = compId.ResourceId } - id := compId.ResourceId kibana, err := client.GetKibanaClient() if err != nil { @@ -184,9 +178,9 @@ func resourceSpaceDelete(ctx context.Context, d *schema.ResourceData, meta inter if diags.HasError() { return diags } - compId, diags := clients.CompositeIdFromStr(d.Id()) - if diags.HasError() { - return diags + id := d.Id() + if compId, diags := clients.CompositeIdFromStr(id); diags == nil { + id = compId.ResourceId } kibana, err := client.GetKibanaClient() @@ -194,7 +188,7 @@ func resourceSpaceDelete(ctx context.Context, d *schema.ResourceData, meta inter return diag.FromErr(err) } - err = kibana.KibanaSpaces.Delete(compId.ResourceId) + err = kibana.KibanaSpaces.Delete(id) if err != nil { return diag.FromErr(err) } diff --git a/internal/kibana/space_test.go b/internal/kibana/space_test.go index 5cef8b750..16a4d25da 100644 --- a/internal/kibana/space_test.go +++ b/internal/kibana/space_test.go @@ -44,7 +44,6 @@ func TestAccResourceSpace(t *testing.T) { func testAccResourceSpaceCreate(id string) string { return fmt.Sprintf(` provider "elasticstack" { - elasticsearch {} kibana {} } @@ -59,7 +58,6 @@ resource "elasticstack_kibana_space" "test_space" { func testAccResourceSpaceUpdate(id string) string { return fmt.Sprintf(` provider "elasticstack" { - elasticsearch {} kibana {} } @@ -82,19 +80,18 @@ func checkResourceSpaceDestroy(s *terraform.State) error { if rs.Type != "elasticstack_kibana_space" { continue } - compId, _ := clients.CompositeIdFromStr(rs.Primary.ID) kibanaClient, err := client.GetKibanaClient() if err != nil { return err } - res, err := kibanaClient.KibanaSpaces.Get(compId.ResourceId) + res, err := kibanaClient.KibanaSpaces.Get(rs.Primary.ID) if err != nil { return err } if res != nil { - return fmt.Errorf("Space (%s) still exists", compId.ResourceId) + return fmt.Errorf("Space (%s) still exists", rs.Primary.ID) } } return nil diff --git a/internal/schema/connection.go b/internal/schema/connection.go index 39b9692de..c77e1a2c8 100644 --- a/internal/schema/connection.go +++ b/internal/schema/connection.go @@ -111,12 +111,9 @@ func GetEsFWConnectionBlock(keyName string) fwschema.Block { } } -func GetKbFWConnectionBlock(keyName string) fwschema.Block { - usernamePath := makePathRef(keyName, "username") - passwordPath := makePathRef(keyName, "password") - - usernameValidators := []validator.String{stringvalidator.AlsoRequires(path.MatchRoot(passwordPath))} - passwordValidators := []validator.String{stringvalidator.AlsoRequires(path.MatchRoot(usernamePath))} +func GetKbFWConnectionBlock() fwschema.Block { + usernamePath := path.MatchRelative().AtParent().AtName("username") + passwordPath := path.MatchRelative().AtParent().AtName("password") return fwschema.ListNestedBlock{ MarkdownDescription: "Kibana connection configuration block.", @@ -125,13 +122,13 @@ func GetKbFWConnectionBlock(keyName string) fwschema.Block { "username": fwschema.StringAttribute{ MarkdownDescription: "Username to use for API authentication to Kibana.", Optional: true, - Validators: usernameValidators, + Validators: []validator.String{stringvalidator.AlsoRequires(passwordPath)}, }, "password": fwschema.StringAttribute{ MarkdownDescription: "Password to use for API authentication to Kibana.", Optional: true, Sensitive: true, - Validators: passwordValidators, + Validators: []validator.String{stringvalidator.AlsoRequires(usernamePath)}, }, "endpoints": fwschema.ListAttribute{ MarkdownDescription: "A comma-separated list of endpoints where the terraform provider will point to, this must include the http(s) schema and port number.", @@ -151,12 +148,9 @@ func GetKbFWConnectionBlock(keyName string) fwschema.Block { } } -func GetFleetFWConnectionBlock(keyName string) fwschema.Block { - usernamePath := makePathRef(keyName, "username") - passwordPath := makePathRef(keyName, "password") - - usernameValidators := []validator.String{stringvalidator.AlsoRequires(path.MatchRoot(passwordPath))} - passwordValidators := []validator.String{stringvalidator.AlsoRequires(path.MatchRoot(usernamePath))} +func GetFleetFWConnectionBlock() fwschema.Block { + usernamePath := path.MatchRelative().AtParent().AtName("username") + passwordPath := path.MatchRelative().AtParent().AtName("password") return fwschema.ListNestedBlock{ MarkdownDescription: "Fleet connection configuration block.", @@ -165,21 +159,21 @@ func GetFleetFWConnectionBlock(keyName string) fwschema.Block { "username": fwschema.StringAttribute{ MarkdownDescription: "Username to use for API authentication to Fleet.", Optional: true, - Validators: usernameValidators, + Validators: []validator.String{stringvalidator.AlsoRequires(passwordPath)}, }, "password": fwschema.StringAttribute{ MarkdownDescription: "Password to use for API authentication to Fleet.", Optional: true, Sensitive: true, - Validators: passwordValidators, + Validators: []validator.String{stringvalidator.AlsoRequires(usernamePath)}, }, "api_key": fwschema.StringAttribute{ MarkdownDescription: "API Key to use for authentication to Fleet.", Optional: true, Sensitive: true, Validators: []validator.String{ - stringvalidator.ConflictsWith(path.MatchRelative().AtParent().AtName("username")), - stringvalidator.ConflictsWith(path.MatchRoot(passwordPath)), + stringvalidator.ConflictsWith(usernamePath), + stringvalidator.ConflictsWith(passwordPath), }, }, "endpoint": fwschema.StringAttribute{ diff --git a/provider/plugin_framework.go b/provider/plugin_framework.go index ad5895141..5175a5256 100644 --- a/provider/plugin_framework.go +++ b/provider/plugin_framework.go @@ -33,8 +33,8 @@ func (p *Provider) Schema(ctx context.Context, req fwprovider.SchemaRequest, res res.Schema = fwschema.Schema{ Blocks: map[string]fwschema.Block{ esKeyName: schema.GetEsFWConnectionBlock(esKeyName), - kbKeyName: schema.GetKbFWConnectionBlock(kbKeyName), - fleetKeyName: schema.GetFleetFWConnectionBlock(fleetKeyName), + kbKeyName: schema.GetKbFWConnectionBlock(), + fleetKeyName: schema.GetFleetFWConnectionBlock(), }, } } diff --git a/provider/provider_test.go b/provider/provider_test.go index 8d081d70d..7ab338c8b 100644 --- a/provider/provider_test.go +++ b/provider/provider_test.go @@ -6,13 +6,17 @@ import ( "testing" "github.com/elastic/terraform-provider-elasticstack/internal/acctest" + "github.com/elastic/terraform-provider-elasticstack/internal/clients/config" "github.com/elastic/terraform-provider-elasticstack/internal/elasticsearch/security" "github.com/elastic/terraform-provider-elasticstack/internal/versionutils" "github.com/elastic/terraform-provider-elasticstack/provider" + "github.com/hashicorp/go-version" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) +var minVersionForFleet = version.Must(version.NewVersion("8.6.0")) + func TestProvider(t *testing.T) { if err := provider.New("dev").InternalValidate(); err != nil { t.Fatalf("Failed to validate provider: %s", err) @@ -36,6 +40,71 @@ func TestElasticsearchAPIKeyConnection(t *testing.T) { }) } +func TestFleetConfiguration(t *testing.T) { + envConfig := config.NewFromEnv("acceptance-testing") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ProtoV5ProviderFactories: acctest.Providers, + Steps: []resource.TestStep{ + { + SkipFunc: versionutils.CheckIfVersionIsUnsupported(minVersionForFleet), + Config: testFleetConfiguration(envConfig), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.elasticstack_fleet_enrollment_tokens.test", "tokens.#"), + ), + }, + }, + }) +} + +func TestKibanaConfiguration(t *testing.T) { + envConfig := config.NewFromEnv("acceptance-testing") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ProtoV5ProviderFactories: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testKibanaConfiguration(envConfig), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("elasticstack_kibana_space.acc_test", "name"), + ), + }, + }, + }) +} + +func testKibanaConfiguration(cfg config.Client) string { + return fmt.Sprintf(` +provider "elasticstack" { + elasticsearch {} + kibana { + endpoints = ["%s"] + username = "%s" + password = "%s" + } +} + +resource "elasticstack_kibana_space" "acc_test" { + space_id = "acc_test_space" + name = "Acceptance Test Space" +}`, cfg.Kibana.Address, cfg.Kibana.Username, cfg.Kibana.Password) +} + +func testFleetConfiguration(cfg config.Client) string { + return fmt.Sprintf(` +provider "elasticstack" { + fleet { + endpoint = "%s" + username = "%s" + password = "%s" + } +} + +data "elasticstack_fleet_enrollment_tokens" "test" {}`, cfg.Fleet.URL, cfg.Fleet.Username, cfg.Fleet.Password) +} + func testElasticsearchConnection(apiKeyName string) string { return fmt.Sprintf(` provider "elasticstack" {