diff --git a/ec/provider.go b/ec/provider.go index b88f654bf..46b56dffe 100644 --- a/ec/provider.go +++ b/ec/provider.go @@ -28,7 +28,6 @@ import ( "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" - "github.com/elastic/terraform-provider-ec/ec/ecresource/deploymentresource" "github.com/elastic/terraform-provider-ec/ec/ecresource/elasticsearchkeystoreresource" "github.com/elastic/terraform-provider-ec/ec/ecresource/extensionresource" "github.com/elastic/terraform-provider-ec/ec/ecresource/trafficfilterassocresource" @@ -70,7 +69,7 @@ func Provider() *schema.Provider { "ec_stack": stackdatasource.DataSource(), }, ResourcesMap: map[string]*schema.Resource{ - "ec_deployment": deploymentresource.Resource(), + // "ec_deployment": deploymentresource.Resource(), "ec_deployment_elasticsearch_keystore": elasticsearchkeystoreresource.Resource(), "ec_deployment_traffic_filter": trafficfilterresource.Resource(), "ec_deployment_traffic_filter_association": trafficfilterassocresource.Resource(), diff --git a/ec/version.go b/ec/version.go index 8582b5a38..e00612ef5 100644 --- a/ec/version.go +++ b/ec/version.go @@ -18,4 +18,4 @@ package ec // Version contains the current terraform provider version. -const Version = "0.4.0-dev" +const Version = "0.5.0-dev" diff --git a/ectpf/deployment_resource.go b/ectpf/deployment_resource.go new file mode 100644 index 000000000..f81d0bb0e --- /dev/null +++ b/ectpf/deployment_resource.go @@ -0,0 +1,260 @@ +// 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 ectpf + +import ( + "context" + + "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" + "github.com/hashicorp/terraform-plugin-log/tflog" + + "github.com/elastic/terraform-provider-ec/ectpf/ecresource/deploymentresource" +) + +// Ensure provider defined types fully satisfy framework interfaces +var _ tpfprovider.ResourceType = deploymentResourceType{} +var _ resource.Resource = deploymentResource{} + +// var _ resource.ResourceWithImportState = deploymentResource{} + +type deploymentResourceType struct{} + +func (t deploymentResourceType) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) { + return tfsdk.Schema{ + // This description is used by the documentation generator and the language server. + MarkdownDescription: "Elastic Cloud Deployment resource", + + Attributes: map[string]tfsdk.Attribute{ + "version": { + Type: types.StringType, + Description: "Required Elastic Stack version to use for all of the deployment resources", + Required: true, + }, + "region": { + Type: types.StringType, + Description: `Required ESS region where to create the deployment, for ECE environments "ece-region" must be set`, + Required: true, + }, + "deployment_template_id": { + Type: types.StringType, + Description: "Required Deployment Template identifier to create the deployment from", + Required: true, + }, + "name": { + Type: types.StringType, + Description: "Optional name for the deployment", + Optional: true, + }, + }, + + Blocks: map[string]tfsdk.Block{ + "elasticsearch": { + NestingMode: tfsdk.BlockNestingModeList, + MaxItems: 1, + Attributes: map[string]tfsdk.Attribute{ + "autoscale": { + Type: types.StringType, + Description: `Enable or disable autoscaling. Defaults to the setting coming from the deployment template. Accepted values are "true" or "false".`, + Computed: true, + Optional: true, + // ValidateFunc: func(i interface{}, s string) ([]string, []error) { + // if _, err := strconv.ParseBool(i.(string)); err != nil { + // return nil, []error{ + // fmt.Errorf("failed parsing autoscale value: %w", err), + // } + // } + // return nil, nil + // }, + }, + + "resource_id": { + Type: types.StringType, + Description: "The Elasticsearch resource unique identifier", + Computed: true, + }, + "region": { + Type: types.StringType, + Description: "The Elasticsearch resource region", + Computed: true, + }, + "https_endpoint": { + Type: types.StringType, + Description: "The Elasticsearch resource HTTPs endpoint", + Computed: true, + }, + }, + + Blocks: map[string]tfsdk.Block{ + "topology": { + NestingMode: tfsdk.BlockNestingModeList, + MinItems: 0, + Attributes: map[string]tfsdk.Attribute{ + "id": { + Type: types.StringType, + Description: `Required topology ID from the deployment template`, + Required: true, + }, + }, + }, + }, + + Description: "Required Elasticsearch resource definition", + }, + }, + }, nil +} + +func (t deploymentResourceType) NewResource(ctx context.Context, in tpfprovider.Provider) (resource.Resource, diag.Diagnostics) { + provider, diags := convertProviderType(in) + + return deploymentResource{ + provider: provider, + }, diags +} + +type deploymentResource struct { + provider scaffoldingProvider +} + +func (r deploymentResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + if !r.provider.configured { + resp.Diagnostics.AddError( + "Provider not configured", + "The provider hasn't been configured before apply, likely because it depends on an unknown value from another resource. This leads to weird stuff happening, so we'd prefer if you didn't do that. Thanks!", + ) + return + } + + var cfg deploymentresource.DeploymentData + diags := req.Config.Get(ctx, &cfg) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + var plan deploymentresource.DeploymentData + diags = req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + deploymentResource, errors := deploymentresource.Create(ctx, r.provider.client, &cfg, &plan) + + if len(errors) > 0 { + for _, err := range errors { + resp.Diagnostics.AddError( + "Cannot create deployment resource", + err.Error(), + ) + } + return + } + + // If applicable, this is a great opportunity to initialize any necessary + // provider client data and make a call using it. + // example, err := d.provider.client.CreateExample(...) + // if err != nil { + // resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create example, got error: %s", err)) + // return + // } + + // For the purposes of this example code, hardcoding a response value to + // save into the Terraform state. + // data.Id = types.String{Value: "example-id"} + + // write logs using the tflog package + // see https://pkg.go.dev/github.com/hashicorp/terraform-plugin-log/tflog + // for more information + tflog.Trace(ctx, "created a resource") + + diags = resp.State.Set(ctx, &deploymentResource) + resp.Diagnostics.Append(diags...) +} + +func (r deploymentResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var state deploymentresource.DeploymentData + + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // If applicable, this is a great opportunity to initialize any necessary + // provider client data and make a call using it. + // example, err := d.provider.client.ReadExample(...) + // if err != nil { + // resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read example, got error: %s", err)) + // return + // } + // r.provider.client + + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) +} + +func (r deploymentResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var data deploymentresource.DeploymentData + + diags := req.Plan.Get(ctx, &data) + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // If applicable, this is a great opportunity to initialize any necessary + // provider client data and make a call using it. + // example, err := d.provider.client.UpdateExample(...) + // if err != nil { + // resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update example, got error: %s", err)) + // return + // } + + diags = resp.State.Set(ctx, &data) + resp.Diagnostics.Append(diags...) +} + +func (r deploymentResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var data deploymentresource.DeploymentData + + diags := req.State.Get(ctx, &data) + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // If applicable, this is a great opportunity to initialize any necessary + // provider client data and make a call using it. + // example, err := d.provider.client.DeleteExample(...) + // if err != nil { + // resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to delete example, got error: %s", err)) + // return + // } +} + +// func (r deploymentResource) ImportState(ctx context.Context, req tfsdk.ImportResourceStateRequest, resp *tfsdk.ImportResourceStateResponse) { +// tfsdk.ResourceImportStatePassthroughID(ctx, tftypes.NewAttributePath().WithAttributeName("id"), req, resp) +// } diff --git a/ectpf/ecresource/deploymentresource/create.go b/ectpf/ecresource/deploymentresource/create.go new file mode 100644 index 000000000..85a8d25c5 --- /dev/null +++ b/ectpf/ecresource/deploymentresource/create.go @@ -0,0 +1,80 @@ +// 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 deploymentresource + +import ( + "context" + "fmt" + + "github.com/elastic/cloud-sdk-go/pkg/api" +) + +// CreateResource will createResource a new deployment from the specified settings. +func Create(ctx context.Context, client *api.API, cfg, plan *DeploymentData) (resp *DeploymentData, errors []error) { + // reqID := deploymentapi.RequestID("") + + // req, err := createResourceToModel(client, cfg, plan) + // if err != nil { + // return nil, []error{err} + // } + + // res, err := deploymentapi.Create(deploymentapi.CreateParams{ + // API: client, + // RequestID: reqID, + // Request: req, + // Overrides: &deploymentapi.PayloadOverrides{ + // Name: plan.Name.Value, + // Version: plan.Version.Value, + // Region: plan.Region.Value, + // }, + // }) + + // if err != nil { + // merr := multierror.NewPrefixed("failed creating deployment", err) + // return nil, []error{merr.Append(newCreationError(reqID))} + // } + + // if err := WaitForPlanCompletion(client, *res.ID); err != nil { + // merr := multierror.NewPrefixed("failed tracking create progress", err) + // return nil, []error{merr.Append(newCreationError(reqID))} + // } + + // d.SetId(*res.ID) + + // if err := handleRemoteClusters(d, client); err != nil { + // errors = append(errors, err) + // } + + /* if errs := readResource(ctx, d, meta); errs != nil { + errors = append(errors, errs...) + } + + if err := parseCredentials(d, res.Resources); err != nil { + errors = append(errors, err) + } + + return errors + */ + return nil, nil +} + +func newCreationError(reqID string) error { + return fmt.Errorf( + `set "request_id" to "%s" to recreate the deployment resources`, reqID, + ) +} diff --git a/ectpf/ecresource/deploymentresource/deployment_data.go b/ectpf/ecresource/deploymentresource/deployment_data.go new file mode 100644 index 000000000..1fe3beaf9 --- /dev/null +++ b/ectpf/ecresource/deploymentresource/deployment_data.go @@ -0,0 +1,42 @@ +// 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 deploymentresource + +import ( + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type DeploymentData struct { + Version types.String `tfsdk:"version"` + Region types.String `tfsdk:"region"` + DeploymentTemplateId types.String `tfsdk:"deployment_template_id"` + Name types.String `tfsdk:"name"` + Elasticsearch ElasticsearchData `tfsdk:"elasticsearch"` +} + +type ElasticsearchData struct { + Autoscale types.String `tfsdk:"autoscale"` + ResourceId types.String `tfsdk:"resource_id"` + Region types.String `tfsdk:"region"` + HttpsEndpoint types.String `tfsdk:"https_endpoint"` + Topology []ElasticsearchTopologyData `tfsdk:"topology"` +} + +type ElasticsearchTopologyData struct { + Id types.String `tfsdk:"id"` +} diff --git a/ectpf/provider.go b/ectpf/provider.go new file mode 100644 index 000000000..49b9aacda --- /dev/null +++ b/ectpf/provider.go @@ -0,0 +1,257 @@ +// 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. + +// New provider during the migration to Terraform Plugin Framework. +// It should host all data sources and resources that migrated to TPF, +// while non-migrated data sources and resouces should be handled by `ec.Provider()`. +// Once all data sources and resources are migrated, +// the provider shall become the only one provider in the repo. + +package ectpf + +import ( + "context" + "fmt" + "os" + + "github.com/hashicorp/terraform-plugin-framework/diag" + tpfprovider "github.com/hashicorp/terraform-plugin-framework/provider" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/elastic/cloud-sdk-go/pkg/api" +) + +const ( + eceOnlyText = "Available only when targeting ECE Installations or Elasticsearch Service Private" + saasRequiredText = "The only valid authentication mechanism for the Elasticsearch Service" + + endpointDesc = "Endpoint where the terraform provider will point to. Defaults to \"%s\"." + insecureDesc = "Allow the provider to skip TLS validation on its outgoing HTTP calls." + timeoutDesc = "Timeout used for individual HTTP calls. Defaults to \"1m\"." + verboseDesc = "When set, a \"request.log\" file will be written with all outgoing HTTP requests. Defaults to \"false\"." + verboseCredsDesc = "When set with verbose, the contents of the Authorization header will not be redacted. Defaults to \"false\"." +) + +var ( + apikeyDesc = fmt.Sprint("API Key to use for API authentication. ", saasRequiredText, ".") + usernameDesc = fmt.Sprint("Username to use for API authentication. ", eceOnlyText, ".") + passwordDesc = fmt.Sprint("Password to use for API authentication. ", eceOnlyText, ".") + + validURLSchemes = []string{"http", "https"} +) + +// Ensure provider defined types fully satisfy framework interfaces +var _ tpfprovider.Provider = &scaffoldingProvider{} + +// provider satisfies the tfsdk.Provider interface and usually is included +// with all Resource and DataSource implementations. +type scaffoldingProvider struct { + // client can contain the upstream provider SDK or HTTP client used to + // communicate with the upstream service. Resource and DataSource + // implementations can then make calls using this client. + // + // TODO: If appropriate, implement upstream provider SDK or HTTP client. + // client vendorsdk.ExampleClient + + // configured is set to true at the end of the Configure method. + // This can be used in Resource and DataSource implementations to verify + // that the provider was previously configured. + configured bool + + // version is set to the provider version on release, "dev" when the + // provider is built and ran locally, and "test" when running acceptance + // testing. + version string + + client *api.API +} + +// providerData can be used to store data from the Terraform configuration. +type providerData struct { + Endpoint types.String `tfsdk:"endpoint"` + Apikey types.String `tfsdk:"apikey"` + Insecure types.Bool `tfsdk:"insecure"` + Timeout types.String `tfsdk:"timeout"` + Verbose types.Bool `tfsdk:"verbose"` +} + +func (p *scaffoldingProvider) Configure(ctx context.Context, req tpfprovider.ConfigureRequest, resp *tpfprovider.ConfigureResponse) { + var data providerData + diags := req.Config.Get(ctx, &data) + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + cfg, err := newAPIConfig(&data) + if err != nil { + resp.Diagnostics.AddError( + "Cannot configure Elastic API", + err.Error(), + ) + return + } + + client, err := api.NewAPI(cfg) + if err != nil { + resp.Diagnostics.AddError( + "Cannot initialise Elastic API client from the configuration", + err.Error(), + ) + return + } + + p.client = client + + p.configured = true +} + +func (p *scaffoldingProvider) GetResources(ctx context.Context) (map[string]tpfprovider.ResourceType, diag.Diagnostics) { + return map[string]tpfprovider.ResourceType{ + "ec_deployment": deploymentResourceType{}, + }, nil +} + +func (p *scaffoldingProvider) GetDataSources(ctx context.Context) (map[string]tpfprovider.DataSourceType, diag.Diagnostics) { + return map[string]tpfprovider.DataSourceType{}, nil +} + +// type endpointPlanModifier struct{} + +// func (*endpointPlanModifier) Description(context.Context) string { +// return "" +// } + +// func (*endpointPlanModifier) MarkdownDescription(context.Context) string { +// return "" +// } + +// func (*endpointPlanModifier) Modify(ctx context.Context, req tfsdk.ModifyAttributePlanRequest, resp *tfsdk.ModifyAttributePlanResponse) { +// if req.AttributeConfig.IsNull() { +// v, err := MultiEnvDefaultFunc([]string{"EC_ENDPOINT", "EC_HOST"}, api.ESSEndpoint) +// if err != nil { +// resp.Diagnostics.AddError( +// `Cannot read endpoint from default environment variables "EC_ENDPOINT", "EC_HOST"`, +// err.Error(), +// ) +// return +// } +// resp.AttributePlan = types.String{Value: v} +// } +// } + +func MultiEnvDefaultFunc(ks []string, def string) (string, error) { + for _, k := range ks { + if v := os.Getenv(k); v != "" { + return v, nil + } + } + return def, nil +} + +func (p *scaffoldingProvider) GetSchema(ctx context.Context) (tfsdk.Schema, diag.Diagnostics) { + return tfsdk.Schema{ + Attributes: map[string]tfsdk.Attribute{ + "endpoint": { + Description: fmt.Sprintf(endpointDesc, api.ESSEndpoint), + Type: types.StringType, + Optional: true, + }, + "apikey": { + Description: apikeyDesc, + Type: types.StringType, + Optional: true, + Sensitive: true, + }, + "username": { + Description: usernameDesc, + Type: types.StringType, + Optional: true, + }, + "password": { + Description: passwordDesc, + Type: types.StringType, + Optional: true, + Sensitive: true, + }, + "insecure": { + Description: "Allow the provider to skip TLS validation on its outgoing HTTP calls.", + Type: types.BoolType, + Optional: true, + }, + "timeout": { + Description: timeoutDesc, + Type: types.StringType, + Optional: true, + }, + "verbose": { + Description: verboseDesc, + Type: types.BoolType, + Optional: true, + }, + "verbose_credentials": { + Description: verboseCredsDesc, + Type: types.BoolType, + Optional: true, + }, + "verbose_file": { + Description: timeoutDesc, + Type: types.StringType, + Optional: true, + }, + }, + }, nil +} + +func New(version string) func() tpfprovider.Provider { + return func() tpfprovider.Provider { + return &scaffoldingProvider{ + version: version, + } + } +} + +// 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 tpfprovider.Provider) (scaffoldingProvider, diag.Diagnostics) { + var diags diag.Diagnostics + + p, ok := in.(*scaffoldingProvider) + + 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 scaffoldingProvider{}, 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 scaffoldingProvider{}, diags + } + + return *p, diags +} diff --git a/ectpf/provider_config.go b/ectpf/provider_config.go new file mode 100644 index 000000000..aad6e6aa2 --- /dev/null +++ b/ectpf/provider_config.go @@ -0,0 +1,66 @@ +// 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 ectpf + +import ( + "fmt" + "net/http" + "os" + "time" + + "github.com/elastic/cloud-sdk-go/pkg/api" + "github.com/elastic/cloud-sdk-go/pkg/auth" +) + +var ( + // defaultTimeout used for all outgoing HTTP requests, keeping it low-ish + // since any requests which timeout due to network factors are retried + // automatically by the SDK 2 times. + defaultTimeout = 40 * time.Second +) + +func newAPIConfig(data *providerData) (api.Config, error) { + var cfg api.Config + + authWriter, err := auth.NewAuthWriter(auth.Config{ + APIKey: data.Apikey.Value, + }) + if err != nil { + return cfg, err + } + + return api.Config{ + ErrorDevice: os.Stdout, + Client: &http.Client{}, + VerboseSettings: api.VerboseSettings{ + Device: os.Stdout, + Verbose: data.Verbose.Value, + RedactAuth: false, + }, + AuthWriter: authWriter, + Host: data.Endpoint.Value, + SkipTLSVerify: data.Insecure.Value, + Timeout: defaultTimeout, + UserAgent: userAgent("0.0.1"), + Retries: 2, + }, nil +} + +func userAgent(v string) string { + return fmt.Sprintf("elastic-terraform-provider2/%s (%s)", v, api.DefaultUserAgent) +} 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 9a9c09d4a..72ba1fb66 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,9 @@ require ( 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.0.0-20181012175058-2f1d1f20f75d // indirect diff --git a/go.sum b/go.sum index 097a6d198..b7ef78c5b 100644 --- a/go.sum +++ b/go.sum @@ -283,6 +283,8 @@ github.com/hashicorp/terraform-exec v0.17.2 h1:EU7i3Fh7vDUI9nNRdMATCEfnm9axzTnad github.com/hashicorp/terraform-exec v0.17.2/go.mod h1:tuIbsL2l4MlwwIZx9HPM+LOV9vVyEfBYu2GsO1uH3/8= github.com/hashicorp/terraform-json v0.14.0 h1:sh9iZ1Y8IFJLx+xQiKHGud6/TSUCM0N8e17dKDpqV7s= github.com/hashicorp/terraform-json v0.14.0/go.mod h1:5A9HIWPkk4e5aeeXIBbkcOvaZbIYnAIkEyqP2pNSckM= +github.com/hashicorp/terraform-plugin-framework v0.11.1 h1:rq8f+TLDO4tJu+n9mMYlDrcRoIdrg0gTUvV2Jr0Ya24= +github.com/hashicorp/terraform-plugin-framework v0.11.1/go.mod h1:GENReHOz6GEt8Jk3UN94vk8BdC6irEHFgN3Z9HPhPUU= github.com/hashicorp/terraform-plugin-go v0.14.0 h1:ttnSlS8bz3ZPYbMb84DpcPhY4F5DsQtcAS7cHo8uvP4= github.com/hashicorp/terraform-plugin-go v0.14.0/go.mod h1:2nNCBeRLaenyQEi78xrGrs9hMbulveqG/zDMQSvVJTE= github.com/hashicorp/terraform-plugin-log v0.7.0 h1:SDxJUyT8TwN4l5b5/VkiTIaQgY6R+Y2BQ0sRZftGKQs= diff --git a/main.go b/main.go index 29889ca0c..9bf88d1e9 100644 --- a/main.go +++ b/main.go @@ -23,6 +23,9 @@ import ( "log" "github.com/elastic/terraform-provider-ec/ec" + "github.com/elastic/terraform-provider-ec/ectpf" + + "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" @@ -50,8 +53,7 @@ func main() { ctx := context.Background() providers := []func() tfprotov6.ProviderServer{ func() tfprotov6.ProviderServer { return upgradedSdkProvider }, - // TODO - // add new v6 provider with `ec_deployment` resource + providerserver.NewProtocol6(ectpf.New(ec.Version)()), } muxServer, err := tf6muxserver.NewMuxServer(ctx, providers...)