From a5de6e998e9c344e1f4f33fb0fd620f5a840e973 Mon Sep 17 00:00:00 2001 From: Dmytro Onishchenko Date: Wed, 7 Sep 2022 12:16:05 +0200 Subject: [PATCH] Migrate resource ec_deployment_traffic_filter_association to terraform-provider-framework --- .github/workflows/go.yml | 1 + ec/acc/acc_prereq.go | 11 +- ...loyment_traffic_filter_association_test.go | 58 ++++ ...filter_association_basic_ignore_changes.tf | 39 +++ .../deploymentdatasource/datasource.go | 16 +- .../deploymentsdatasource/datasource.go | 11 +- ec/ecdatasource/stackdatasource/datasource.go | 11 +- .../trafficfilterassocresource/create.go | 42 ++- .../trafficfilterassocresource/delete.go | 34 +- .../trafficfilterassocresource/delete_test.go | 113 ------ .../trafficfilterassocresource/expanders.go | 33 -- .../expanders_test.go | 61 ---- .../flatteners_test.go | 120 ------- .../import_state.go | 44 +++ .../trafficfilterassocresource/read.go | 47 ++- .../trafficfilterassocresource/read_test.go | 114 ------ .../trafficfilterassocresource/resource.go | 40 --- .../resource_test.go | 324 ++++++++++++++++++ .../trafficfilterassocresource/schema.go | 77 ++++- .../{testutils.go => update.go} | 12 +- .../flatteners/flatten_endpoint.go} | 35 +- .../flatteners/flatten_tags.go} | 12 +- .../flatteners/flatten_tags_test.go} | 9 +- ec/internal/planmodifier/default_from_env.go | 17 + ec/internal/planmodifier/default_value.go | 17 + ec/internal/provider.go | 32 ++ ec/internal/validators/knownvalidator.go | 17 + ec/internal/validators/urlvalidator.go | 24 +- ec/provider.go | 35 +- ec/provider_config.go | 9 +- examples/deployment_with_init/main.tf | 18 +- go.mod | 3 +- go.sum | 2 + main.go | 7 +- 34 files changed, 796 insertions(+), 649 deletions(-) create mode 100644 ec/acc/testdata/deployment_traffic_filter_association_basic_ignore_changes.tf delete mode 100644 ec/ecresource/trafficfilterassocresource/delete_test.go delete mode 100644 ec/ecresource/trafficfilterassocresource/expanders.go delete mode 100644 ec/ecresource/trafficfilterassocresource/expanders_test.go delete mode 100644 ec/ecresource/trafficfilterassocresource/flatteners_test.go create mode 100644 ec/ecresource/trafficfilterassocresource/import_state.go delete mode 100644 ec/ecresource/trafficfilterassocresource/read_test.go delete mode 100644 ec/ecresource/trafficfilterassocresource/resource.go create mode 100644 ec/ecresource/trafficfilterassocresource/resource_test.go rename ec/ecresource/trafficfilterassocresource/{testutils.go => update.go} (73%) rename ec/{ecresource/trafficfilterassocresource/flatteners.go => internal/flatteners/flatten_endpoint.go} (57%) rename ec/{ecdatasource/deploymentdatasource/flatteners_tags.go => internal/flatteners/flatten_tags.go} (82%) rename ec/{ecdatasource/deploymentdatasource/flatteners_tags_test.go => internal/flatteners/flatten_tags_test.go} (92%) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 76d776287..47eb58721 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -22,6 +22,7 @@ jobs: uses: hashicorp/setup-terraform@v2 with: terraform_version: "1.x.x" + terraform_wrapper: false - name: Cache Go Modules uses: actions/cache@v3 diff --git a/ec/acc/acc_prereq.go b/ec/acc/acc_prereq.go index 9e77eea24..e079cd6e0 100644 --- a/ec/acc/acc_prereq.go +++ b/ec/acc/acc_prereq.go @@ -19,13 +19,14 @@ package acc import ( "context" - "github.com/hashicorp/terraform-plugin-framework/providerserver" - "github.com/hashicorp/terraform-plugin-go/tfprotov5" - "github.com/hashicorp/terraform-plugin-mux/tf5muxserver" "net/http" "os" "testing" + "github.com/hashicorp/terraform-plugin-framework/providerserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-mux/tf5muxserver" + "github.com/elastic/cloud-sdk-go/pkg/api" "github.com/elastic/cloud-sdk-go/pkg/auth" "github.com/elastic/terraform-provider-ec/ec" @@ -44,9 +45,7 @@ func protoV5ProviderFactories() map[string]func() (tfprotov5.ProviderServer, err func() tfprotov5.ProviderServer { return ec.LegacyProvider().GRPCProvider() }, - func() tfprotov5.ProviderServer { - return providerserver.NewProtocol5(ec.New())() - }, + providerserver.NewProtocol5(ec.New("acc-tests")), ) }, } diff --git a/ec/acc/deployment_traffic_filter_association_test.go b/ec/acc/deployment_traffic_filter_association_test.go index 0fee2adc6..ab657ad1e 100644 --- a/ec/acc/deployment_traffic_filter_association_test.go +++ b/ec/acc/deployment_traffic_filter_association_test.go @@ -72,6 +72,64 @@ func TestAccDeploymentTrafficFilterAssociation_basic(t *testing.T) { }) } +func TestAccDeploymentTrafficFilterAssociation_UpgradeFrom0_4_1(t *testing.T) { + resName := "ec_deployment_traffic_filter.tf_assoc" + resAssocName := "ec_deployment_traffic_filter_association.tf_assoc" + randomName := acctest.RandomWithPrefix(prefix) + startCfg := "testdata/deployment_traffic_filter_association_basic.tf" + ignoreChangesCfgFile := "testdata/deployment_traffic_filter_association_basic_ignore_changes.tf" + cfg := fixtureAccDeploymentTrafficFilterResourceAssociationBasic(t, startCfg, randomName, getRegion(), defaultTemplate) + ignoreChangesCfg := fixtureAccDeploymentTrafficFilterResourceAssociationBasic(t, ignoreChangesCfgFile, randomName, getRegion(), defaultTemplate) + + // Required because of a bug - see https://discuss.hashicorp.com/t/acceptance-testing-sdk-framework-upgrade-issue/44166/2 + externalProviderConfig := ` +terraform { + required_providers { + ec = { + source = "elastic/ec" + version = "0.4.1" + } + } +}` + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + CheckDestroy: testAccDeploymentTrafficFilterDestroy, + Steps: []resource.TestStep{ + { + ExternalProviders: map[string]resource.ExternalProvider{ + "ec": { + VersionConstraint: "0.4.1", + Source: "elastic/ec", + }, + }, + // Expects a non-empty plan since "ec_deployment.traffic_filter" + // will have changes due to the traffic filter association. + ExpectNonEmptyPlan: true, + Config: cfg + externalProviderConfig, + Check: checkBasicDeploymentTrafficFilterAssociationResource( + resName, resAssocName, randomName, + resource.TestCheckResourceAttr(resName, "include_by_default", "false"), + resource.TestCheckResourceAttr(resName, "type", "ip"), + resource.TestCheckResourceAttr(resName, "rule.#", "1"), + resource.TestCheckResourceAttr(resName, "rule.0.source", "0.0.0.0/0"), + ), + }, + { + PlanOnly: true, + ProtoV5ProviderFactories: testAccProviderFactory, + Config: ignoreChangesCfg, + Check: checkBasicDeploymentTrafficFilterAssociationResource( + resName, resAssocName, randomName, + resource.TestCheckResourceAttr(resName, "include_by_default", "false"), + resource.TestCheckResourceAttr(resName, "type", "ip"), + resource.TestCheckResourceAttr(resName, "rule.#", "1"), + resource.TestCheckResourceAttr(resName, "rule.0.source", "0.0.0.0/0"), + ), + }, + }, + }) +} + func fixtureAccDeploymentTrafficFilterResourceAssociationBasic(t *testing.T, fileName, name, region, depTpl string) string { t.Helper() diff --git a/ec/acc/testdata/deployment_traffic_filter_association_basic_ignore_changes.tf b/ec/acc/testdata/deployment_traffic_filter_association_basic_ignore_changes.tf new file mode 100644 index 000000000..ce1bce981 --- /dev/null +++ b/ec/acc/testdata/deployment_traffic_filter_association_basic_ignore_changes.tf @@ -0,0 +1,39 @@ +data "ec_stack" "latest" { + version_regex = "latest" + region = "%s" +} + +resource "ec_deployment" "tf_assoc" { + name = "%s" + region = "%s" + version = data.ec_stack.latest.version + deployment_template_id = "%s" + + elasticsearch { + topology { + id = "hot_content" + size = "1g" + } + } + + kibana {} + + lifecycle { + ignore_changes = [traffic_filter] + } +} + +resource "ec_deployment_traffic_filter" "tf_assoc" { + name = "%s" + region = "%s" + type = "ip" + + rule { + source = "0.0.0.0/0" + } +} + +resource "ec_deployment_traffic_filter_association" "tf_assoc" { + traffic_filter_id = ec_deployment_traffic_filter.tf_assoc.id + deployment_id = ec_deployment.tf_assoc.id +} diff --git a/ec/ecdatasource/deploymentdatasource/datasource.go b/ec/ecdatasource/deploymentdatasource/datasource.go index e940639b9..1239f6041 100644 --- a/ec/ecdatasource/deploymentdatasource/datasource.go +++ b/ec/ecdatasource/deploymentdatasource/datasource.go @@ -20,7 +20,7 @@ package deploymentdatasource import ( "context" "fmt" - "github.com/elastic/terraform-provider-ec/ec/internal" + "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/provider" @@ -30,6 +30,8 @@ import ( "github.com/elastic/cloud-sdk-go/pkg/api/deploymentapi/deputil" "github.com/elastic/cloud-sdk-go/pkg/models" + "github.com/elastic/terraform-provider-ec/ec/internal" + "github.com/elastic/terraform-provider-ec/ec/internal/flatteners" "github.com/elastic/terraform-provider-ec/ec/internal/util" ) @@ -37,10 +39,12 @@ var _ provider.DataSourceType = (*DataSourceType)(nil) type DataSourceType struct{} -func (s DataSourceType) NewDataSource(ctx context.Context, p provider.Provider) (datasource.DataSource, diag.Diagnostics) { +func (s DataSourceType) NewDataSource(ctx context.Context, in provider.Provider) (datasource.DataSource, diag.Diagnostics) { + p, diags := internal.ConvertProviderType(in) + return &deploymentDataSource{ - p: p.(internal.Provider), - }, nil + p: p, + }, diags } var _ datasource.DataSource = (*deploymentDataSource)(nil) @@ -115,7 +119,9 @@ func modelToState(ctx context.Context, res *models.DeploymentGetResponse, state diags.Append(flattenIntegrationsServerResources(ctx, res.Resources.IntegrationsServer, &state.IntegrationsServer)...) diags.Append(flattenEnterpriseSearchResources(ctx, res.Resources.EnterpriseSearch, &state.EnterpriseSearch)...) - state.Tags = flattenTags(res.Metadata) + if res.Metadata != nil { + state.Tags = flatteners.FlattenTags(res.Metadata.Tags) + } return diags } diff --git a/ec/ecdatasource/deploymentsdatasource/datasource.go b/ec/ecdatasource/deploymentsdatasource/datasource.go index 0fbd64040..7f4b6b64c 100644 --- a/ec/ecdatasource/deploymentsdatasource/datasource.go +++ b/ec/ecdatasource/deploymentsdatasource/datasource.go @@ -20,13 +20,14 @@ package deploymentsdatasource import ( "context" "fmt" + "strconv" + "github.com/elastic/terraform-provider-ec/ec/internal" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/provider" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" - "strconv" "github.com/elastic/cloud-sdk-go/pkg/api/deploymentapi" "github.com/elastic/cloud-sdk-go/pkg/models" @@ -37,10 +38,12 @@ var _ provider.DataSourceType = (*DataSourceType)(nil) type DataSourceType struct{} -func (s DataSourceType) NewDataSource(ctx context.Context, p provider.Provider) (datasource.DataSource, diag.Diagnostics) { +func (s DataSourceType) NewDataSource(ctx context.Context, in provider.Provider) (datasource.DataSource, diag.Diagnostics) { + p, diags := internal.ConvertProviderType(in) + return &deploymentsDataSource{ - p: p.(internal.Provider), - }, nil + p: p, + }, diags } var _ datasource.DataSource = (*deploymentsDataSource)(nil) diff --git a/ec/ecdatasource/stackdatasource/datasource.go b/ec/ecdatasource/stackdatasource/datasource.go index f0fa5002e..200c72f71 100644 --- a/ec/ecdatasource/stackdatasource/datasource.go +++ b/ec/ecdatasource/stackdatasource/datasource.go @@ -20,6 +20,8 @@ package stackdatasource import ( "context" "fmt" + "regexp" + "github.com/elastic/cloud-sdk-go/pkg/api/stackapi" "github.com/elastic/cloud-sdk-go/pkg/models" "github.com/elastic/terraform-provider-ec/ec/internal" @@ -28,17 +30,18 @@ import ( "github.com/hashicorp/terraform-plugin-framework/provider" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" - "regexp" ) var _ provider.DataSourceType = (*DataSourceType)(nil) type DataSourceType struct{} -func (s DataSourceType) NewDataSource(ctx context.Context, p provider.Provider) (datasource.DataSource, diag.Diagnostics) { +func (s DataSourceType) NewDataSource(ctx context.Context, in provider.Provider) (datasource.DataSource, diag.Diagnostics) { + p, diags := internal.ConvertProviderType(in) + return &stackDataSource{ - p: p.(internal.Provider), - }, nil + p: p, + }, diags } var _ datasource.DataSource = (*stackDataSource)(nil) diff --git a/ec/ecresource/trafficfilterassocresource/create.go b/ec/ecresource/trafficfilterassocresource/create.go index c1c75e46e..7c2946995 100644 --- a/ec/ecresource/trafficfilterassocresource/create.go +++ b/ec/ecresource/trafficfilterassocresource/create.go @@ -19,29 +19,35 @@ package trafficfilterassocresource import ( "context" - "strconv" - "strings" - - "github.com/elastic/cloud-sdk-go/pkg/api" + "fmt" "github.com/elastic/cloud-sdk-go/pkg/api/deploymentapi/trafficfilterapi" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types" ) -// create will create a new deployment traffic filter ruleset association. -func create(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client := meta.(*api.API) - params := expand(d) - params.API = client +func (t trafficFilterAssocResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { + var newState modelV0 - if err := trafficfilterapi.CreateAssociation(params); err != nil { - return diag.FromErr(err) + diags := request.Plan.Get(ctx, &newState) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return } - d.SetId(hashID(params.EntityID, params.ID)) - return read(ctx, d, meta) -} + if err := trafficfilterapi.CreateAssociation(trafficfilterapi.CreateAssociationParams{ + API: t.provider.GetClient(), + ID: newState.TrafficFilterID.Value, + EntityID: newState.DeploymentID.Value, + EntityType: entityTypeDeployment, + }); err != nil { + response.Diagnostics.AddError(err.Error(), err.Error()) + return + } -func hashID(elem ...string) string { - return strconv.Itoa(schema.HashString(strings.Join(elem, "-"))) + newState.ID = types.String{Value: fmt.Sprintf("%v-%v", newState.DeploymentID.Value, newState.TrafficFilterID.Value)} + diags = response.State.Set(ctx, newState) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } } diff --git a/ec/ecresource/trafficfilterassocresource/delete.go b/ec/ecresource/trafficfilterassocresource/delete.go index 2e77312c8..8d4103b55 100644 --- a/ec/ecresource/trafficfilterassocresource/delete.go +++ b/ec/ecresource/trafficfilterassocresource/delete.go @@ -20,31 +20,31 @@ package trafficfilterassocresource import ( "context" "errors" - - "github.com/elastic/cloud-sdk-go/pkg/api" "github.com/elastic/cloud-sdk-go/pkg/api/deploymentapi/trafficfilterapi" "github.com/elastic/cloud-sdk-go/pkg/client/deployments_traffic_filter" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-framework/resource" ) -// delete will delete an existing deployment traffic filter ruleset association. -func delete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - var client = meta.(*api.API) +func (t trafficFilterAssocResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { + var state modelV0 - params := expand(d) - params.API = client + diags := request.State.Get(ctx, &state) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } - if err := trafficfilterapi.DeleteAssociation(trafficfilterapi.DeleteAssociationParams(params)); err != nil { - if associationDeleted(err) { - d.SetId("") - return nil + if err := trafficfilterapi.DeleteAssociation(trafficfilterapi.DeleteAssociationParams{ + API: t.provider.GetClient(), + ID: state.TrafficFilterID.Value, + EntityID: state.DeploymentID.Value, + EntityType: entityTypeDeployment, + }); err != nil { + if !associationDeleted(err) { + response.Diagnostics.AddError(err.Error(), err.Error()) + return } - return diag.FromErr(err) } - - d.SetId("") - return nil } func associationDeleted(err error) bool { diff --git a/ec/ecresource/trafficfilterassocresource/delete_test.go b/ec/ecresource/trafficfilterassocresource/delete_test.go deleted file mode 100644 index bc738a70b..000000000 --- a/ec/ecresource/trafficfilterassocresource/delete_test.go +++ /dev/null @@ -1,113 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package trafficfilterassocresource - -import ( - "context" - "testing" - - "github.com/elastic/cloud-sdk-go/pkg/api" - "github.com/elastic/cloud-sdk-go/pkg/api/mock" - "github.com/elastic/terraform-provider-ec/ec/internal/util" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/stretchr/testify/assert" -) - -func Test_delete(t *testing.T) { - tc500Err := util.NewResourceData(t, util.ResDataParams{ - ID: mock.ValidClusterID, - State: newSampleTrafficFilterAssociation(), - Schema: newSchema(), - }) - wantTC500 := util.NewResourceData(t, util.ResDataParams{ - ID: mock.ValidClusterID, - State: newSampleTrafficFilterAssociation(), - Schema: newSchema(), - }) - - tc404Err := util.NewResourceData(t, util.ResDataParams{ - ID: mock.ValidClusterID, - State: newSampleTrafficFilterAssociation(), - Schema: newSchema(), - }) - wantTC404 := util.NewResourceData(t, util.ResDataParams{ - ID: mock.ValidClusterID, - State: newSampleTrafficFilterAssociation(), - Schema: newSchema(), - }) - wantTC404.SetId("") - type args struct { - ctx context.Context - d *schema.ResourceData - meta interface{} - } - tests := []struct { - name string - args args - want diag.Diagnostics - wantRD *schema.ResourceData - }{ - { - name: "returns an error when it receives a 500", - args: args{ - d: tc500Err, - meta: api.NewMock(mock.NewErrorResponse(500, mock.APIError{ - Code: "some", Message: "message", - })), - }, - want: diag.Diagnostics{ - { - Severity: diag.Error, - Summary: "api error: 1 error occurred:\n\t* some: message\n\n", - }, - }, - wantRD: wantTC500, - }, - { - name: "returns nil and unsets the state when the error is known", - args: args{ - d: tc404Err, - meta: api.NewMock(mock.NewErrorResponse(404, mock.APIError{ - Code: "some", Message: "message", - })), - }, - want: nil, - wantRD: wantTC404, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := delete(tt.args.ctx, tt.args.d, tt.args.meta) - assert.Equal(t, tt.want, got) - var want interface{} - if tt.wantRD != nil { - if s := tt.wantRD.State(); s != nil { - want = s.Attributes - } - } - - var gotState interface{} - if s := tt.args.d.State(); s != nil { - gotState = s.Attributes - } - - assert.Equal(t, want, gotState) - }) - } -} diff --git a/ec/ecresource/trafficfilterassocresource/expanders.go b/ec/ecresource/trafficfilterassocresource/expanders.go deleted file mode 100644 index 185c53635..000000000 --- a/ec/ecresource/trafficfilterassocresource/expanders.go +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package trafficfilterassocresource - -import ( - "github.com/elastic/cloud-sdk-go/pkg/api/deploymentapi/trafficfilterapi" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" -) - -const entityType = "deployment" - -func expand(d *schema.ResourceData) trafficfilterapi.CreateAssociationParams { - return trafficfilterapi.CreateAssociationParams{ - ID: d.Get("traffic_filter_id").(string), - EntityID: d.Get("deployment_id").(string), - EntityType: entityType, - } -} diff --git a/ec/ecresource/trafficfilterassocresource/expanders_test.go b/ec/ecresource/trafficfilterassocresource/expanders_test.go deleted file mode 100644 index 798b9f6ba..000000000 --- a/ec/ecresource/trafficfilterassocresource/expanders_test.go +++ /dev/null @@ -1,61 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package trafficfilterassocresource - -import ( - "testing" - - "github.com/elastic/cloud-sdk-go/pkg/api/deploymentapi/trafficfilterapi" - "github.com/elastic/cloud-sdk-go/pkg/api/mock" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/stretchr/testify/assert" - - "github.com/elastic/terraform-provider-ec/ec/internal/util" -) - -func Test_expand(t *testing.T) { - rd := util.NewResourceData(t, util.ResDataParams{ - State: newSampleTrafficFilterAssociation(), - ID: "123451", - Schema: newSchema(), - }) - type args struct { - d *schema.ResourceData - } - tests := []struct { - name string - args args - want trafficfilterapi.CreateAssociationParams - }{ - { - name: "expands the resource data", - args: args{d: rd}, - want: trafficfilterapi.CreateAssociationParams{ - ID: mockTrafficFilterID, - EntityID: mock.ValidClusterID, - EntityType: entityType, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := expand(tt.args.d) - assert.Equal(t, tt.want, got) - }) - } -} diff --git a/ec/ecresource/trafficfilterassocresource/flatteners_test.go b/ec/ecresource/trafficfilterassocresource/flatteners_test.go deleted file mode 100644 index 62d66ac99..000000000 --- a/ec/ecresource/trafficfilterassocresource/flatteners_test.go +++ /dev/null @@ -1,120 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package trafficfilterassocresource - -import ( - "testing" - - "github.com/elastic/cloud-sdk-go/pkg/api/mock" - "github.com/elastic/cloud-sdk-go/pkg/models" - "github.com/elastic/cloud-sdk-go/pkg/util/ec" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/stretchr/testify/assert" - - "github.com/elastic/terraform-provider-ec/ec/internal/util" -) - -func Test_flatten(t *testing.T) { - rd := util.NewResourceData(t, util.ResDataParams{ - State: newSampleTrafficFilterAssociation(), - ID: "123451", - Schema: newSchema(), - }) - - wantNotFoundRd := util.NewResourceData(t, util.ResDataParams{ - State: newSampleTrafficFilterAssociation(), - ID: "123451", - Schema: newSchema(), - }) - - _ = wantNotFoundRd.Set("deployment_id", "") - _ = wantNotFoundRd.Set("traffic_filter_id", "") - type args struct { - res *models.TrafficFilterRulesetInfo - d *schema.ResourceData - } - tests := []struct { - name string - args args - want *schema.ResourceData - err error - }{ - { - name: "empty response returns nil", - args: args{d: rd}, - }, - { - name: "flattens the response", - args: args{d: rd, - res: &models.TrafficFilterRulesetInfo{ - Associations: []*models.FilterAssociation{ - { - EntityType: ec.String("cluster"), - ID: ec.String("someid"), - }, - { - EntityType: ec.String(entityType), - ID: ec.String(mock.ValidClusterID), - }, - }, - }, - }, - want: rd, - }, - { - name: "flattens the response even when the association has been removed externally", - args: args{d: rd, - res: &models.TrafficFilterRulesetInfo{ - Associations: []*models.FilterAssociation{{ - EntityType: ec.String("cluster"), - ID: ec.String("someid"), - }}, - }, - }, - want: wantNotFoundRd, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := flatten(tt.args.res, tt.args.d) - if tt.err != nil { - assert.EqualError(t, err, tt.err.Error()) - } else { - assert.NoError(t, err) - } - - if tt.args.res == nil { - return - } - - wantState := tt.want.State() - if wantState == nil { - tt.want.SetId("some") - wantState = tt.want.State() - } - - gotState := tt.args.d.State() - if gotState == nil { - tt.args.d.SetId("some") - gotState = tt.want.State() - } - - assert.Equal(t, wantState.Attributes, gotState.Attributes) - }) - } -} diff --git a/ec/ecresource/trafficfilterassocresource/import_state.go b/ec/ecresource/trafficfilterassocresource/import_state.go new file mode 100644 index 000000000..22d8c3e30 --- /dev/null +++ b/ec/ecresource/trafficfilterassocresource/import_state.go @@ -0,0 +1,44 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package trafficfilterassocresource + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "strings" +) + +func (t trafficFilterAssocResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { + idParts := strings.Split(request.ID, ",") + + if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" { + response.Diagnostics.AddError( + "Unexpected Import Identifier", + fmt.Sprintf("Expected import identifier with format: deployment_id,traffic_filter_id. Got: %q", request.ID), + ) + return + } + deploymentId := idParts[0] + trafficFilterId := idParts[1] + + response.Diagnostics.Append(response.State.SetAttribute(ctx, path.Root("id"), fmt.Sprintf("%v-%v", deploymentId, trafficFilterId))...) + response.Diagnostics.Append(response.State.SetAttribute(ctx, path.Root("deployment_id"), deploymentId)...) + response.Diagnostics.Append(response.State.SetAttribute(ctx, path.Root("traffic_filter_id"), trafficFilterId)...) +} diff --git a/ec/ecresource/trafficfilterassocresource/read.go b/ec/ecresource/trafficfilterassocresource/read.go index 938ac7dd2..31a901b1e 100644 --- a/ec/ecresource/trafficfilterassocresource/read.go +++ b/ec/ecresource/trafficfilterassocresource/read.go @@ -19,35 +19,48 @@ package trafficfilterassocresource import ( "context" - - "github.com/elastic/cloud-sdk-go/pkg/api" "github.com/elastic/cloud-sdk-go/pkg/api/deploymentapi/trafficfilterapi" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/elastic/terraform-provider-ec/ec/internal/util" + "github.com/hashicorp/terraform-plugin-framework/resource" ) -// read queries the remote deployment traffic filter ruleset association and -// updates the local state. -func read(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - var client = meta.(*api.API) +func (t trafficFilterAssocResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { + var state modelV0 + + diags := request.State.Get(ctx, &state) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + res, err := trafficfilterapi.Get(trafficfilterapi.GetParams{ - API: client, - ID: d.Get("traffic_filter_id").(string), + API: t.provider.GetClient(), + ID: state.TrafficFilterID.Value, IncludeAssociations: true, }) if err != nil { if util.TrafficFilterNotFound(err) { - d.SetId("") - return nil + response.State.RemoveResource(ctx) + return } - return diag.FromErr(err) + response.Diagnostics.AddError(err.Error(), err.Error()) + return } - if err := flatten(res, d); err != nil { - return diag.FromErr(err) + if res == nil { + response.State.RemoveResource(ctx) + return } - return nil + var found bool + for _, assoc := range res.Associations { + if *assoc.EntityType == entityTypeDeployment && *assoc.ID == state.DeploymentID.Value { + found = true + } + } + + if !found { + response.State.RemoveResource(ctx) + return + } } diff --git a/ec/ecresource/trafficfilterassocresource/read_test.go b/ec/ecresource/trafficfilterassocresource/read_test.go deleted file mode 100644 index 4dd437ffa..000000000 --- a/ec/ecresource/trafficfilterassocresource/read_test.go +++ /dev/null @@ -1,114 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package trafficfilterassocresource - -import ( - "context" - "testing" - - "github.com/elastic/cloud-sdk-go/pkg/api" - "github.com/elastic/cloud-sdk-go/pkg/api/mock" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/stretchr/testify/assert" - - "github.com/elastic/terraform-provider-ec/ec/internal/util" -) - -func Test_read(t *testing.T) { - tc500Err := util.NewResourceData(t, util.ResDataParams{ - ID: mock.ValidClusterID, - State: newSampleTrafficFilterAssociation(), - Schema: newSchema(), - }) - wantTC500 := util.NewResourceData(t, util.ResDataParams{ - ID: mock.ValidClusterID, - State: newSampleTrafficFilterAssociation(), - Schema: newSchema(), - }) - - tc404Err := util.NewResourceData(t, util.ResDataParams{ - ID: mock.ValidClusterID, - State: newSampleTrafficFilterAssociation(), - Schema: newSchema(), - }) - wantTC404 := util.NewResourceData(t, util.ResDataParams{ - ID: mock.ValidClusterID, - State: newSampleTrafficFilterAssociation(), - Schema: newSchema(), - }) - wantTC404.SetId("") - type args struct { - ctx context.Context - d *schema.ResourceData - meta interface{} - } - tests := []struct { - name string - args args - want diag.Diagnostics - wantRD *schema.ResourceData - }{ - { - name: "returns an error when it receives a 500", - args: args{ - d: tc500Err, - meta: api.NewMock(mock.NewErrorResponse(500, mock.APIError{ - Code: "some", Message: "message", - })), - }, - want: diag.Diagnostics{ - { - Severity: diag.Error, - Summary: "api error: 1 error occurred:\n\t* some: message\n\n", - }, - }, - wantRD: wantTC500, - }, - { - name: "returns nil and unsets the state when the error is known", - args: args{ - d: tc404Err, - meta: api.NewMock(mock.NewErrorResponse(404, mock.APIError{ - Code: "some", Message: "message", - })), - }, - want: nil, - wantRD: wantTC404, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := read(tt.args.ctx, tt.args.d, tt.args.meta) - assert.Equal(t, tt.want, got) - var want interface{} - if tt.wantRD != nil { - if s := tt.wantRD.State(); s != nil { - want = s.Attributes - } - } - - var gotState interface{} - if s := tt.args.d.State(); s != nil { - gotState = s.Attributes - } - - assert.Equal(t, want, gotState) - }) - } -} diff --git a/ec/ecresource/trafficfilterassocresource/resource.go b/ec/ecresource/trafficfilterassocresource/resource.go deleted file mode 100644 index 4a402d894..000000000 --- a/ec/ecresource/trafficfilterassocresource/resource.go +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package trafficfilterassocresource - -import ( - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" -) - -// Resource returns the ec_deployment_traffic_filter_association resource schema. -func Resource() *schema.Resource { - return &schema.Resource{ - Description: "Elastic Cloud deployment traffic filtering association", - Schema: newSchema(), - - CreateContext: create, - ReadContext: read, - DeleteContext: delete, - - Timeouts: &schema.ResourceTimeout{ - Default: schema.DefaultTimeout(10 * time.Minute), - }, - } -} diff --git a/ec/ecresource/trafficfilterassocresource/resource_test.go b/ec/ecresource/trafficfilterassocresource/resource_test.go new file mode 100644 index 000000000..8b64425d3 --- /dev/null +++ b/ec/ecresource/trafficfilterassocresource/resource_test.go @@ -0,0 +1,324 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package trafficfilterassocresource_test + +import ( + "github.com/elastic/cloud-sdk-go/pkg/api" + "github.com/elastic/cloud-sdk-go/pkg/api/mock" + "github.com/elastic/terraform-provider-ec/ec" + "github.com/hashicorp/terraform-plugin-framework/providerserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "net/url" + "regexp" + "testing" + + r "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestResourceTrafficFilterAssoc(t *testing.T) { + + r.UnitTest(t, r.TestCase{ + ProtoV5ProviderFactories: protoV5ProviderFactoriesWithMockClient( + api.NewMock( + createResponse(), + readResponse(), + readResponse(), + readResponse(), + readResponse(), + deleteResponse(), + ), + ), + Steps: []r.TestStep{ + { // Create resource + Config: trafficFilterAssoc, + Check: checkResource(), + }, + { // Ensure that it can be successfully read + PlanOnly: true, + Config: trafficFilterAssoc, + Check: checkResource(), + }, + { // Delete resource + Destroy: true, + Config: trafficFilterAssoc, + }, + }, + }) +} + +func TestResourceTrafficFilterAssoc_externalDeletion1(t *testing.T) { + r.UnitTest(t, r.TestCase{ + ProtoV5ProviderFactories: protoV5ProviderFactoriesWithMockClient( + api.NewMock( + createResponse(), + readResponse(), + readResponseAssociationDeleted(), + ), + ), + Steps: []r.TestStep{ + { // Create resource + Config: trafficFilterAssoc, + Check: checkResource(), + }, + { // Ensure that it gets unset if deleted externally + PlanOnly: true, + ExpectNonEmptyPlan: true, + Config: trafficFilterAssoc, + Check: checkResourceDeleted(), + }, + }, + }) +} +func TestResourceTrafficFilterAssoc_externalDeletion2(t *testing.T) { + r.UnitTest(t, r.TestCase{ + ProtoV5ProviderFactories: protoV5ProviderFactoriesWithMockClient( + api.NewMock( + createResponse(), + readResponse(), + readResponseTrafficFilterDeleted(), + ), + ), + Steps: []r.TestStep{ + { // Create resource + Config: trafficFilterAssoc, + Check: checkResource(), + }, + { // Ensure that it gets unset if deleted externally + PlanOnly: true, + ExpectNonEmptyPlan: true, + Config: trafficFilterAssoc, + Check: checkResourceDeleted(), + }, + }, + }) +} + +func TestResourceTrafficFilterAssoc_gracefulDeletion(t *testing.T) { + r.UnitTest(t, r.TestCase{ + ProtoV5ProviderFactories: protoV5ProviderFactoriesWithMockClient( + api.NewMock( + createResponse(), + readResponse(), + readResponse(), + alreadyDeletedResponse(), + ), + ), + Steps: []r.TestStep{ + { // Create resource + Config: trafficFilterAssoc, + Check: checkResource(), + }, + { // Delete resource + Destroy: true, + Config: trafficFilterAssoc, + }, + }, + }) +} + +func TestResourceTrafficFilterAssoc_failedDeletion(t *testing.T) { + r.UnitTest(t, r.TestCase{ + ProtoV5ProviderFactories: protoV5ProviderFactoriesWithMockClient( + api.NewMock( + createResponse(), + readResponse(), + readResponse(), + failedDeletionResponse(), + deleteResponse(), + ), + ), + Steps: []r.TestStep{ + { + Config: trafficFilterAssoc, + }, + { + Destroy: true, + Config: trafficFilterAssoc, + ExpectError: regexp.MustCompile(`internal.server.error: There was an internal server error`), + }, + }, + }) +} + +func TestResourceTrafficFilterAssoc_importState(t *testing.T) { + r.UnitTest(t, r.TestCase{ + ProtoV5ProviderFactories: protoV5ProviderFactoriesWithMockClient( + api.NewMock( + readResponse(), + ), + ), + Steps: []r.TestStep{ + { + ImportState: true, + ImportStateId: "0a592ab2c5baf0fa95c77ac62135782e,9db94e68e2f040a19dfb664d0e83bc2a", + ResourceName: "ec_deployment_traffic_filter_association.test1", + Config: trafficFilterAssoc, + Check: checkResource(), + }, + }, + }) +} + +const trafficFilterAssoc = ` + resource "ec_deployment_traffic_filter_association" "test1" { + traffic_filter_id = "9db94e68e2f040a19dfb664d0e83bc2a" + deployment_id = "0a592ab2c5baf0fa95c77ac62135782e" + } +` + +func checkResource() r.TestCheckFunc { + return r.ComposeAggregateTestCheckFunc( + r.TestCheckResourceAttr("ec_deployment_traffic_filter_association.test1", "id", "0a592ab2c5baf0fa95c77ac62135782e-9db94e68e2f040a19dfb664d0e83bc2a"), + r.TestCheckResourceAttr("ec_deployment_traffic_filter_association.test1", "traffic_filter_id", "9db94e68e2f040a19dfb664d0e83bc2a"), + r.TestCheckResourceAttr("ec_deployment_traffic_filter_association.test1", "deployment_id", "0a592ab2c5baf0fa95c77ac62135782e"), + ) +} + +func checkResourceDeleted() r.TestCheckFunc { + return r.ComposeAggregateTestCheckFunc( + r.TestCheckNoResourceAttr("ec_deployment_traffic_filter_association.test1", "id"), + r.TestCheckNoResourceAttr("ec_deployment_traffic_filter_association.test1", "traffic_filter_id"), + r.TestCheckNoResourceAttr("ec_deployment_traffic_filter_association.test1", "deployment_id"), + ) +} + +func createResponse() mock.Response { + return mock.New200ResponseAssertion( + &mock.RequestAssertion{ + Host: api.DefaultMockHost, + Header: api.DefaultWriteMockHeaders, + Method: "POST", + Path: "/api/v1/deployments/traffic-filter/rulesets/9db94e68e2f040a19dfb664d0e83bc2a/associations", + Query: url.Values{}, + Body: mock.NewStringBody(`{"entity_type":"deployment","id":"0a592ab2c5baf0fa95c77ac62135782e"}` + "\n"), + }, + mock.NewStringBody(`{"entity_type":"deployment","id":"0a592ab2c5baf0fa95c77ac62135782e"}`), + ) +} + +func readResponse() mock.Response { + return mock.New200ResponseAssertion( + &mock.RequestAssertion{ + Host: api.DefaultMockHost, + Header: api.DefaultReadMockHeaders, + Method: "GET", + Path: "/api/v1/deployments/traffic-filter/rulesets/9db94e68e2f040a19dfb664d0e83bc2a", + Query: url.Values{ + "include_associations": []string{"true"}, + }, + }, + mock.NewStringBody(`{ + "id": "9db94e68e2f040a19dfb664d0e83bc2a", + "name": "dummy", + "type": "ip", + "include_by_default": false, + "region": "us-east-1", + "rules": [{"id": "6e4c8874f90d4793a2290f8199461952","source": "127.0.0.1"} ], + "associations": [{"entity_type": "deployment", "id": "0a592ab2c5baf0fa95c77ac62135782e"}], + "total_associations": 1 + }`, + ), + ) +} + +func readResponseAssociationDeleted() mock.Response { + return mock.New200ResponseAssertion( + &mock.RequestAssertion{ + Host: api.DefaultMockHost, + Header: api.DefaultReadMockHeaders, + Method: "GET", + Path: "/api/v1/deployments/traffic-filter/rulesets/9db94e68e2f040a19dfb664d0e83bc2a", + Query: url.Values{ + "include_associations": []string{"true"}, + }, + }, + mock.NewStringBody(`{ + "id": "9db94e68e2f040a19dfb664d0e83bc2a", + "name": "dummy", + "type": "ip", + "include_by_default": false, + "region": "us-east-1", + "rules": [{"id": "6e4c8874f90d4793a2290f8199461952","source": "127.0.0.1"} ], + "associations": [{"entity_type": "deployment", "id": "some-unrelated-id"}], + "total_associations": 1 + }`, + ), + ) +} + +func readResponseTrafficFilterDeleted() mock.Response { + return mock.New404ResponseAssertion( + &mock.RequestAssertion{ + Host: api.DefaultMockHost, + Header: api.DefaultReadMockHeaders, + Method: "GET", + Path: "/api/v1/deployments/traffic-filter/rulesets/9db94e68e2f040a19dfb664d0e83bc2a", + Query: url.Values{ + "include_associations": []string{"true"}, + }, + }, + mock.NewStringBody(`{ }`), + ) +} + +func deleteResponse() mock.Response { + return mock.New200ResponseAssertion( + &mock.RequestAssertion{ + Host: api.DefaultMockHost, + Header: api.DefaultReadMockHeaders, + Method: "DELETE", + Path: "/api/v1/deployments/traffic-filter/rulesets/9db94e68e2f040a19dfb664d0e83bc2a/associations/deployment/0a592ab2c5baf0fa95c77ac62135782e", + Query: url.Values{}, + }, + mock.NewStringBody(`{}`), + ) +} + +func alreadyDeletedResponse() mock.Response { + return mock.New404ResponseAssertion( + &mock.RequestAssertion{ + Host: api.DefaultMockHost, + Header: api.DefaultReadMockHeaders, + Method: "DELETE", + Path: "/api/v1/deployments/traffic-filter/rulesets/9db94e68e2f040a19dfb664d0e83bc2a/associations/deployment/0a592ab2c5baf0fa95c77ac62135782e", + Query: url.Values{}, + }, + mock.NewStringBody(`{ }`), + ) +} +func failedDeletionResponse() mock.Response { + mock.SampleInternalError() + return mock.New500ResponseAssertion( + &mock.RequestAssertion{ + Host: api.DefaultMockHost, + Header: api.DefaultReadMockHeaders, + Method: "DELETE", + Path: "/api/v1/deployments/traffic-filter/rulesets/9db94e68e2f040a19dfb664d0e83bc2a/associations/deployment/0a592ab2c5baf0fa95c77ac62135782e", + Query: url.Values{}, + }, + mock.SampleInternalError().Response.Body, + ) +} + +func protoV5ProviderFactoriesWithMockClient(client *api.API) map[string]func() (tfprotov5.ProviderServer, error) { + return map[string]func() (tfprotov5.ProviderServer, error){ + "ec": func() (tfprotov5.ProviderServer, error) { + return providerserver.NewProtocol5(ec.ProviderWithClient(client, "unit-tests"))(), nil + }, + } +} diff --git a/ec/ecresource/trafficfilterassocresource/schema.go b/ec/ecresource/trafficfilterassocresource/schema.go index ec5e91d87..bd0460d84 100644 --- a/ec/ecresource/trafficfilterassocresource/schema.go +++ b/ec/ecresource/trafficfilterassocresource/schema.go @@ -18,23 +18,68 @@ package trafficfilterassocresource import ( - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "context" + "github.com/elastic/terraform-provider-ec/ec/internal" + "github.com/hashicorp/terraform-plugin-framework/diag" + tpfprovider "github.com/hashicorp/terraform-plugin-framework/provider" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" ) -// newSchema returns the schema for an "ec_deployment_traffic_filter_association" resource. -func newSchema() map[string]*schema.Schema { - return map[string]*schema.Schema{ - "deployment_id": { - Type: schema.TypeString, - Description: `Required deployment ID where the traffic filter will be associated`, - Required: true, - ForceNew: true, - }, - "traffic_filter_id": { - Type: schema.TypeString, - Description: "Required traffic filter ruleset ID to tie to a deployment", - Required: true, - ForceNew: true, +// Ensure provider defined types fully satisfy framework interfaces +var _ tpfprovider.ResourceType = ResourceType{} +var _ resource.Resource = trafficFilterAssocResource{} + +var _ resource.ResourceWithImportState = trafficFilterAssocResource{} + +type ResourceType struct{} + +const entityTypeDeployment = "deployment" + +func (t ResourceType) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) { + return tfsdk.Schema{ + Attributes: map[string]tfsdk.Attribute{ + "deployment_id": { + Type: types.StringType, + Description: `Required deployment ID where the traffic filter will be associated`, + Required: true, + PlanModifiers: []tfsdk.AttributePlanModifier{ + resource.RequiresReplace(), + }, + }, + "traffic_filter_id": { + Type: types.StringType, + Description: "Required traffic filter ruleset ID to tie to a deployment", + Required: true, + PlanModifiers: []tfsdk.AttributePlanModifier{ + resource.RequiresReplace(), + }, + }, + // Computed attributes + "id": { + Type: types.StringType, + Computed: true, + MarkdownDescription: "Unique identifier of this resource.", + }, }, - } + }, nil +} + +func (t ResourceType) NewResource(_ context.Context, provider tpfprovider.Provider) (resource.Resource, diag.Diagnostics) { + p, diags := internal.ConvertProviderType(provider) + + return &trafficFilterAssocResource{ + provider: p, + }, diags +} + +type trafficFilterAssocResource struct { + provider internal.Provider +} + +type modelV0 struct { + ID types.String `tfsdk:"id"` + DeploymentID types.String `tfsdk:"deployment_id"` + TrafficFilterID types.String `tfsdk:"traffic_filter_id"` } diff --git a/ec/ecresource/trafficfilterassocresource/testutils.go b/ec/ecresource/trafficfilterassocresource/update.go similarity index 73% rename from ec/ecresource/trafficfilterassocresource/testutils.go rename to ec/ecresource/trafficfilterassocresource/update.go index b81f2f193..b5a2017c5 100644 --- a/ec/ecresource/trafficfilterassocresource/testutils.go +++ b/ec/ecresource/trafficfilterassocresource/update.go @@ -18,14 +18,10 @@ package trafficfilterassocresource import ( - "github.com/elastic/cloud-sdk-go/pkg/api/mock" + "context" + "github.com/hashicorp/terraform-plugin-framework/resource" ) -var mockTrafficFilterID = "420b7b540dfc967a7a649c18e2fce4e4" - -func newSampleTrafficFilterAssociation() map[string]interface{} { - return map[string]interface{}{ - "deployment_id": mock.ValidClusterID, - "traffic_filter_id": mockTrafficFilterID, - } +func (t trafficFilterAssocResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { + panic("ec_deployment_traffic_filter_association resources can not be updated!") } diff --git a/ec/ecresource/trafficfilterassocresource/flatteners.go b/ec/internal/flatteners/flatten_endpoint.go similarity index 57% rename from ec/ecresource/trafficfilterassocresource/flatteners.go rename to ec/internal/flatteners/flatten_endpoint.go index 5c419f4c8..3af63a361 100644 --- a/ec/ecresource/trafficfilterassocresource/flatteners.go +++ b/ec/internal/flatteners/flatten_endpoint.go @@ -15,35 +15,28 @@ // specific language governing permissions and limitations // under the License. -package trafficfilterassocresource +package flatteners import ( + "fmt" + "github.com/elastic/cloud-sdk-go/pkg/models" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func flatten(res *models.TrafficFilterRulesetInfo, d *schema.ResourceData) error { - if res == nil { - return nil +// FlattenClusterEndpoint receives a ClusterMetadataInfo, parses the http and +// https endpoints and returns a map with two keys: `http_endpoint` and +// `https_endpoint` +func FlattenEndpoints(metadata *models.ClusterMetadataInfo) (httpEndpoint string, httpsEndpoint string) { + if metadata == nil || metadata.Endpoint == "" || metadata.Ports == nil { + return } - var found bool - deploymentID := d.Get("deployment_id").(string) - for _, assoc := range res.Associations { - if *assoc.EntityType == entityType && *assoc.ID == deploymentID { - found = true - } + if metadata.Ports.HTTP != nil { + httpEndpoint = fmt.Sprintf("http://%s:%d", metadata.Endpoint, *metadata.Ports.HTTP) } - if !found { - if err := d.Set("deployment_id", ""); err != nil { - return err - } - if err := d.Set("traffic_filter_id", ""); err != nil { - return err - } - d.SetId("") + if metadata.Ports.HTTPS != nil { + httpsEndpoint = fmt.Sprintf("https://%s:%d", metadata.Endpoint, *metadata.Ports.HTTPS) } - - return nil + return } diff --git a/ec/ecdatasource/deploymentdatasource/flatteners_tags.go b/ec/internal/flatteners/flatten_tags.go similarity index 82% rename from ec/ecdatasource/deploymentdatasource/flatteners_tags.go rename to ec/internal/flatteners/flatten_tags.go index 1605b0dec..57d05c01e 100644 --- a/ec/ecdatasource/deploymentdatasource/flatteners_tags.go +++ b/ec/internal/flatteners/flatten_tags.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package deploymentdatasource +package flatteners import ( "github.com/elastic/cloud-sdk-go/pkg/models" @@ -25,18 +25,12 @@ import ( // flattenTags takes in Deployment Metadata resource models and returns its // Tags in flattened form. -func flattenTags(metadata *models.DeploymentMetadata) types.Map { - - if metadata == nil || metadata.Tags == nil { - return types.Map{ElemType: types.StringType, Elems: map[string]attr.Value{}} - } - +func FlattenTags(metadataItems []*models.MetadataItem) types.Map { var tags = make(map[string]attr.Value) - for _, res := range metadata.Tags { + for _, res := range metadataItems { if res.Key != nil { tags[*res.Key] = types.String{Value: *res.Value} } } return types.Map{ElemType: types.StringType, Elems: tags} - } diff --git a/ec/ecdatasource/deploymentdatasource/flatteners_tags_test.go b/ec/internal/flatteners/flatten_tags_test.go similarity index 92% rename from ec/ecdatasource/deploymentdatasource/flatteners_tags_test.go rename to ec/internal/flatteners/flatten_tags_test.go index 6bc722462..9b28f6f85 100644 --- a/ec/ecdatasource/deploymentdatasource/flatteners_tags_test.go +++ b/ec/internal/flatteners/flatten_tags_test.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -package deploymentdatasource +package flatteners import ( "context" @@ -35,11 +35,6 @@ func TestFlattenTags(t *testing.T) { args args want map[string]string }{ - { - name: "flattens no metadata tags when empty", - args: args{}, - want: map[string]string{}, - }, { name: "flattens no metadata tags when empty", args: args{metadata: &models.DeploymentMetadata{}}, @@ -76,7 +71,7 @@ func TestFlattenTags(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - result := flattenTags(tt.args.metadata) + result := FlattenTags(tt.args.metadata.Tags) got := make(map[string]string, len(result.Elems)) result.ElementsAs(context.Background(), &got, false) assert.Equal(t, tt.want, got) diff --git a/ec/internal/planmodifier/default_from_env.go b/ec/internal/planmodifier/default_from_env.go index 04de4cc43..77b2fd3cc 100644 --- a/ec/internal/planmodifier/default_from_env.go +++ b/ec/internal/planmodifier/default_from_env.go @@ -1,3 +1,20 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + package planmodifier import ( diff --git a/ec/internal/planmodifier/default_value.go b/ec/internal/planmodifier/default_value.go index 6f3b8e4b9..75ad85026 100644 --- a/ec/internal/planmodifier/default_value.go +++ b/ec/internal/planmodifier/default_value.go @@ -1,3 +1,20 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + // NOTE! copied from terraform-provider-tls package planmodifier diff --git a/ec/internal/provider.go b/ec/internal/provider.go index b407dd1ca..ce0e3f6aa 100644 --- a/ec/internal/provider.go +++ b/ec/internal/provider.go @@ -18,7 +18,10 @@ package internal import ( + "fmt" + "github.com/elastic/cloud-sdk-go/pkg/api" + "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/provider" ) @@ -27,3 +30,32 @@ type Provider interface { provider.Provider GetClient() *api.API } + +// ConvertProviderType is a helper function for NewResource and NewDataSource +// implementations to associate the concrete provider type. Alternatively, +// this helper can be skipped and the provider type can be directly type +// asserted (e.g. provider: in.(*provider)), however using this can prevent +// potential panics. +func ConvertProviderType(in provider.Provider) (Provider, diag.Diagnostics) { + var diags diag.Diagnostics + + p, ok := in.(Provider) + + if !ok { + diags.AddError( + "Unexpected Provider Instance Type", + fmt.Sprintf("While creating the data source or resource, an unexpected provider type (%T) was received. This is always a bug in the provider code and should be reported to the provider developers.", p), + ) + return p, diags + } + + if p == nil { + diags.AddError( + "Unexpected Provider Instance Type", + "While creating the data source or resource, an unexpected empty provider instance was received. This is always a bug in the provider code and should be reported to the provider developers.", + ) + return p, diags + } + + return p, diags +} diff --git a/ec/internal/validators/knownvalidator.go b/ec/internal/validators/knownvalidator.go index 82593e66c..129c93506 100644 --- a/ec/internal/validators/knownvalidator.go +++ b/ec/internal/validators/knownvalidator.go @@ -1,3 +1,20 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + package validators import ( diff --git a/ec/internal/validators/urlvalidator.go b/ec/internal/validators/urlvalidator.go index a66f44d34..8de0dbc78 100644 --- a/ec/internal/validators/urlvalidator.go +++ b/ec/internal/validators/urlvalidator.go @@ -1,13 +1,31 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + package validators import ( "context" "fmt" + "net/url" + "strings" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" "golang.org/x/exp/slices" - "net/url" - "strings" ) type isURLWithSchemeValidator struct { @@ -79,5 +97,5 @@ func (v isURLWithSchemeValidator) Validate(ctx context.Context, req tfsdk.Valida } func IsURLWithSchemeValidator(validSchemes []string) tfsdk.AttributeValidator { - return isURLWithSchemeValidator{} + return isURLWithSchemeValidator{ValidSchemes: validSchemes} } diff --git a/ec/provider.go b/ec/provider.go index 917474531..c613f2c9d 100644 --- a/ec/provider.go +++ b/ec/provider.go @@ -20,6 +20,8 @@ package ec import ( "context" "fmt" + "time" + "github.com/elastic/terraform-provider-ec/ec/ecdatasource/deploymentdatasource" "github.com/elastic/terraform-provider-ec/ec/ecdatasource/deploymentsdatasource" "github.com/elastic/terraform-provider-ec/ec/ecdatasource/stackdatasource" @@ -34,7 +36,6 @@ import ( "github.com/elastic/terraform-provider-ec/ec/internal/validators" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - "time" "github.com/elastic/cloud-sdk-go/pkg/api" "github.com/hashicorp/terraform-plugin-framework/diag" @@ -74,11 +75,10 @@ func LegacyProvider() *schema.Provider { Schema: newSchema(), DataSourcesMap: map[string]*schema.Resource{}, ResourcesMap: map[string]*schema.Resource{ - "ec_deployment": deploymentresource.Resource(), - "ec_deployment_elasticsearch_keystore": elasticsearchkeystoreresource.Resource(), - "ec_deployment_traffic_filter": trafficfilterresource.Resource(), - "ec_deployment_traffic_filter_association": trafficfilterassocresource.Resource(), - "ec_deployment_extension": extensionresource.Resource(), + "ec_deployment": deploymentresource.Resource(), + "ec_deployment_elasticsearch_keystore": elasticsearchkeystoreresource.Resource(), + "ec_deployment_traffic_filter": trafficfilterresource.Resource(), + "ec_deployment_extension": extensionresource.Resource(), }, } } @@ -138,18 +138,23 @@ func newSchema() map[string]*schema.Schema { } } -func New() provider.Provider { - return &Provider{} +func New(version string) provider.Provider { + return &Provider{version: version} +} + +func ProviderWithClient(client *api.API, version string) provider.Provider { + return &Provider{client: client, version: version} } var _ internal.Provider = (*Provider)(nil) func (p *Provider) GetClient() *api.API { - return p.Client + return p.client } type Provider struct { - Client *api.API + version string + client *api.API } func (p *Provider) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { @@ -223,6 +228,10 @@ type providerData struct { } func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest, res *provider.ConfigureResponse) { + if p.client != nil { + return + } + // Retrieve provider data from configuration var config providerData diags := req.Config.Get(ctx, &config) @@ -336,7 +345,7 @@ func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest, return } - p.Client, err = api.NewAPI(cfg) + p.client, err = api.NewAPI(cfg) if err != nil { res.Diagnostics.AddWarning( "Unable to create api Client config", @@ -347,7 +356,9 @@ func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest, } func (p *Provider) GetResources(_ context.Context) (map[string]provider.ResourceType, diag.Diagnostics) { - return map[string]provider.ResourceType{}, nil + return map[string]provider.ResourceType{ + "ec_deployment_traffic_filter_association": trafficfilterassocresource.ResourceType{}, + }, nil } func (p *Provider) GetDataSources(_ context.Context) (map[string]provider.DataSourceType, diag.Diagnostics) { diff --git a/ec/provider_config.go b/ec/provider_config.go index acef22ef5..6e8969fd5 100644 --- a/ec/provider_config.go +++ b/ec/provider_config.go @@ -20,13 +20,14 @@ package ec import ( "context" "fmt" - "github.com/elastic/terraform-provider-ec/ec/internal/util" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "net/http" "os" "time" + "github.com/elastic/terraform-provider-ec/ec/internal/util" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/elastic/cloud-sdk-go/pkg/api" "github.com/elastic/cloud-sdk-go/pkg/auth" ) @@ -129,7 +130,7 @@ func verboseSettings(name string, verbose, redactAuth bool) (api.VerboseSettings } return api.VerboseSettings{ - Verbose: true, + Verbose: verbose, RedactAuth: redactAuth, Device: f, }, nil diff --git a/examples/deployment_with_init/main.tf b/examples/deployment_with_init/main.tf index b381e5491..06597b49c 100644 --- a/examples/deployment_with_init/main.tf +++ b/examples/deployment_with_init/main.tf @@ -1,16 +1,10 @@ resource "null_resource" "bootstrap-elasticsearch" { provisioner "local-exec" { - command = data.template_file.elasticsearch-configuration.rendered - } -} - -data "template_file" "elasticsearch-configuration" { - template = file("es_config.sh") - depends_on = [ec_deployment.example_minimal] - vars = { # Created servers and appropriate AZs - elastic-user = ec_deployment.example_minimal.elasticsearch_username - elastic-password = ec_deployment.example_minimal.elasticsearch_password - es-url = ec_deployment.example_minimal.elasticsearch[0].https_endpoint + command = templatefile("es_config.sh", { + elastic-user = ec_deployment.example_minimal.elasticsearch_username + elastic-password = ec_deployment.example_minimal.elasticsearch_password + es-url = ec_deployment.example_minimal.elasticsearch[0].https_endpoint + }) } -} \ No newline at end of file +} diff --git a/go.mod b/go.mod index f2c63afd2..2eb44e9e5 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,14 @@ module github.com/elastic/terraform-provider-ec go 1.19 require ( + github.com/blang/semver v3.5.1+incompatible github.com/blang/semver/v4 v4.0.0 github.com/elastic/cloud-sdk-go v1.10.0 github.com/go-openapi/runtime v0.24.1 github.com/go-openapi/strfmt v0.21.3 github.com/hashicorp/terraform-plugin-framework v0.11.1 github.com/hashicorp/terraform-plugin-go v0.14.0 + github.com/hashicorp/terraform-plugin-log v0.7.0 github.com/hashicorp/terraform-plugin-mux v0.7.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.21.0 github.com/stretchr/testify v1.8.0 @@ -46,7 +48,6 @@ require ( github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-exec v0.17.2 // indirect github.com/hashicorp/terraform-json v0.14.0 // indirect - github.com/hashicorp/terraform-plugin-log v0.7.0 // indirect github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c // indirect github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 // indirect github.com/hashicorp/yamux v0.1.1 // indirect diff --git a/go.sum b/go.sum index d1e0d7ea1..c4c8cf567 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,8 @@ github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:W github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= diff --git a/main.go b/main.go index 1e989d2fe..f265a1c85 100644 --- a/main.go +++ b/main.go @@ -20,10 +20,11 @@ package main import ( "context" "flag" - "github.com/hashicorp/terraform-plugin-framework/providerserver" "log" "github.com/elastic/terraform-provider-ec/ec" + + "github.com/hashicorp/terraform-plugin-framework/providerserver" "github.com/hashicorp/terraform-plugin-go/tfprotov6" "github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server" "github.com/hashicorp/terraform-plugin-mux/tf5to6server" @@ -51,9 +52,7 @@ func main() { ctx := context.Background() providers := []func() tfprotov6.ProviderServer{ func() tfprotov6.ProviderServer { return upgradedSdkProvider }, - func() tfprotov6.ProviderServer { - return providerserver.NewProtocol6(ec.New())() - }, + providerserver.NewProtocol6(ec.New(ec.Version)), } muxServer, err := tf6muxserver.NewMuxServer(ctx, providers...)