Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CDPCP-11100 Async resource creation #77

Merged
merged 1 commit into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions resources/datalake/common_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package datalake

import (
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
Expand All @@ -30,6 +31,15 @@ var generalAttributes = map[string]schema.Attribute{
MarkdownDescription: "Polling related configuration options that could specify various values that will be used during CDP resource creation.",
Optional: true,
Attributes: map[string]schema.Attribute{
"async": schema.BoolAttribute{
MarkdownDescription: "Boolean value that specifies if Terraform should wait for resource creation/deletion.",
Optional: true,
Computed: true,
Default: booldefault.StaticBool(false),
PlanModifiers: []planmodifier.Bool{
boolplanmodifier.UseStateForUnknown(),
},
},
"polling_timeout": schema.Int64Attribute{
MarkdownDescription: "Timeout value in minutes that specifies for how long should the polling go for resource creation/deletion.",
Default: int64default.StaticInt64(60),
Expand Down
16 changes: 10 additions & 6 deletions resources/datalake/resource_aws_datalake.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,11 @@ func (r *awsDatalakeResource) Create(ctx context.Context, req resource.CreateReq
return
}

if err := waitForDatalakeToBeRunning(ctx, state.DatalakeName.ValueString(), time.Hour, r.client.Datalake, state.PollingOptions); err != nil {
utils.AddDatalakeDiagnosticsError(err, &resp.Diagnostics, "create AWS Datalake")
return
if !state.PollingOptions.Async.ValueBool() {
if err := waitForDatalakeToBeRunning(ctx, state.DatalakeName.ValueString(), time.Hour, r.client.Datalake, state.PollingOptions); err != nil {
utils.AddDatalakeDiagnosticsError(err, &resp.Diagnostics, "create AWS Datalake")
return
}
}

descParams := operations.NewDescribeDatalakeParamsWithContext(ctx)
Expand Down Expand Up @@ -404,9 +406,11 @@ func (r *awsDatalakeResource) Delete(ctx context.Context, req resource.DeleteReq
return
}

if err := waitForDatalakeToBeDeleted(ctx, state.DatalakeName.ValueString(), time.Hour, r.client.Datalake, state.PollingOptions); err != nil {
daszabo marked this conversation as resolved.
Show resolved Hide resolved
utils.AddDatalakeDiagnosticsError(err, &resp.Diagnostics, "delete AWS Datalake")
return
if !state.PollingOptions.Async.ValueBool() {
if err := waitForDatalakeToBeDeleted(ctx, state.DatalakeName.ValueString(), time.Hour, r.client.Datalake, state.PollingOptions); err != nil {
utils.AddDatalakeDiagnosticsError(err, &resp.Diagnostics, "delete AWS Datalake")
return
}
}
}

Expand Down
16 changes: 10 additions & 6 deletions resources/datalake/resource_azure_datalake.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,11 @@ func (r *azureDatalakeResource) Create(ctx context.Context, req resource.CreateR
return
}

if err := waitForDatalakeToBeRunning(ctx, state.DatalakeName.ValueString(), time.Hour, r.client.Datalake, state.PollingOptions); err != nil {
utils.AddDatalakeDiagnosticsError(err, &resp.Diagnostics, "create Azure Datalake")
return
if !state.PollingOptions.Async.ValueBool() {
if err := waitForDatalakeToBeRunning(ctx, state.DatalakeName.ValueString(), time.Hour, r.client.Datalake, state.PollingOptions); err != nil {
utils.AddDatalakeDiagnosticsError(err, &resp.Diagnostics, "create AWS Datalake")
return
}
}

descParams := operations.NewDescribeDatalakeParamsWithContext(ctx)
Expand Down Expand Up @@ -359,8 +361,10 @@ func (r *azureDatalakeResource) Delete(ctx context.Context, req resource.DeleteR
return
}

if err := waitForDatalakeToBeDeleted(ctx, state.DatalakeName.ValueString(), time.Hour, r.client.Datalake, state.PollingOptions); err != nil {
utils.AddDatalakeDiagnosticsError(err, &resp.Diagnostics, "delete Azure Datalake")
return
if !state.PollingOptions.Async.ValueBool() {
if err := waitForDatalakeToBeDeleted(ctx, state.DatalakeName.ValueString(), time.Hour, r.client.Datalake, state.PollingOptions); err != nil {
utils.AddDatalakeDiagnosticsError(err, &resp.Diagnostics, "delete Azure Datalake")
return
}
}
}
16 changes: 10 additions & 6 deletions resources/datalake/resource_gcp_datalake.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,11 @@ func (r *gcpDatalakeResource) Create(ctx context.Context, req resource.CreateReq
return
}

if err := waitForDatalakeToBeRunning(ctx, state.DatalakeName.ValueString(), time.Hour, r.client.Datalake, state.PollingOptions); err != nil {
utils.AddDatalakeDiagnosticsError(err, &resp.Diagnostics, "create GCP Datalake")
return
if !state.PollingOptions.Async.ValueBool() {
if err := waitForDatalakeToBeRunning(ctx, state.DatalakeName.ValueString(), time.Hour, r.client.Datalake, state.PollingOptions); err != nil {
utils.AddDatalakeDiagnosticsError(err, &resp.Diagnostics, "create AWS Datalake")
return
}
}

descParams := operations.NewDescribeDatalakeParamsWithContext(ctx)
Expand Down Expand Up @@ -163,8 +165,10 @@ func (r *gcpDatalakeResource) Delete(ctx context.Context, req resource.DeleteReq
return
}

if err := waitForDatalakeToBeDeleted(ctx, state.DatalakeName.ValueString(), time.Hour, r.client.Datalake, state.PollingOptions); err != nil {
utils.AddDatalakeDiagnosticsError(err, &resp.Diagnostics, "delete GCP Datalake")
return
if !state.PollingOptions.Async.ValueBool() {
if err := waitForDatalakeToBeDeleted(ctx, state.DatalakeName.ValueString(), time.Hour, r.client.Datalake, state.PollingOptions); err != nil {
utils.AddDatalakeDiagnosticsError(err, &resp.Diagnostics, "delete GCP Datalake")
return
}
}
}
10 changes: 10 additions & 0 deletions resources/datalake/schema_aws_datalake.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package datalake

import (
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier"
Expand All @@ -35,6 +36,15 @@ var awsDatalakeResourceSchema = schema.Schema{
MarkdownDescription: "Polling related configuration options that could specify various values that will be used during CDP resource creation.",
Optional: true,
Attributes: map[string]schema.Attribute{
"async": schema.BoolAttribute{
MarkdownDescription: "Boolean value that specifies if Terraform should wait for resource creation/deletion.",
Optional: true,
Computed: true,
Default: booldefault.StaticBool(true),
PlanModifiers: []planmodifier.Bool{
boolplanmodifier.UseStateForUnknown(),
},
},
"polling_timeout": schema.Int64Attribute{
MarkdownDescription: "Timeout value in minutes that specifies for how long should the polling go for resource creation/deletion.",
Default: int64default.StaticInt64(60),
Expand Down
10 changes: 10 additions & 0 deletions resources/datalake/schema_azure_datalake.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package datalake

import (
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier"
Expand All @@ -35,6 +36,15 @@ var azureDatalakeResourceSchema = schema.Schema{
MarkdownDescription: "Polling related configuration options that could specify various values that will be used during CDP resource creation.",
Optional: true,
Attributes: map[string]schema.Attribute{
"async": schema.BoolAttribute{
MarkdownDescription: "Boolean value that specifies if Terraform should wait for resource creation/deletion.",
Optional: true,
Computed: true,
Default: booldefault.StaticBool(true),
PlanModifiers: []planmodifier.Bool{
boolplanmodifier.UseStateForUnknown(),
},
},
"polling_timeout": schema.Int64Attribute{
MarkdownDescription: "Timeout value in minutes that specifies for how long should the polling go for resource creation/deletion.",
Default: int64default.StaticInt64(60),
Expand Down
6 changes: 1 addition & 5 deletions resources/environments/converter_gcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,8 @@ func toGcpEnvironmentResource(ctx context.Context, env *environmentsmodels.Envir
model.StatusReason = types.StringValue(env.StatusReason)
tflog.Info(ctx, "about to convert tags.")
if env.Tags != nil {
merged := env.Tags.Defaults
for k, v := range env.Tags.UserDefined {
merged[k] = v
}
var tagDiags diag.Diagnostics
tagMap, tagDiags := types.MapValueFrom(ctx, types.StringType, merged)
tagMap, tagDiags := types.MapValueFrom(ctx, types.StringType, env.Tags.UserDefined)
diags.Append(tagDiags...)
model.Tags = tagMap
}
Expand Down
21 changes: 13 additions & 8 deletions resources/environments/environment_action_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import (
"context"
"time"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-log/tflog"

"github.com/cloudera/terraform-provider-cdp/cdp-sdk-go/cdp"
Expand All @@ -28,7 +30,7 @@ const (
timeoutOneHour = time.Hour * 1
)

func describeEnvironmentWithDiagnosticHandle(envName string, id string, ctx context.Context, client *cdp.Client, resp *resource.ReadResponse) (*environmentsmodels.Environment, error) {
func describeEnvironmentWithDiagnosticHandle(envName string, id string, ctx context.Context, client *cdp.Client, diags *diag.Diagnostics, state *tfsdk.State) (*environmentsmodels.Environment, error) {
tflog.Info(ctx, "About to describe environment '"+envName+"'.")
params := operations.NewDescribeEnvironmentParamsWithContext(ctx)
params.WithInput(&environmentsmodels.DescribeEnvironmentRequest{
Expand All @@ -38,20 +40,20 @@ func describeEnvironmentWithDiagnosticHandle(envName string, id string, ctx cont
if err != nil {
tflog.Warn(ctx, "Something happened during environment fetch: "+err.Error())
if isEnvNotFoundError(err) {
resp.Diagnostics.AddWarning("Resource not found on provider", "Environment not found, removing from state.")
diags.AddWarning("Resource not found on provider", "Environment not found, removing from state.")
tflog.Warn(ctx, "Environment not found, removing from state", map[string]interface{}{
"id": id,
})
resp.State.RemoveResource(ctx)
state.RemoveResource(ctx)
return nil, err
}
utils.AddEnvironmentDiagnosticsError(err, &resp.Diagnostics, "read Environment")
utils.AddEnvironmentDiagnosticsError(err, diags, "read Environment")
return nil, err
}
return utils.LogEnvironmentSilently(ctx, descEnvResp.GetPayload().Environment, describeLogPrefix), nil
}

func deleteEnvironmentWithDiagnosticHandle(environmentName string, ctx context.Context, client *cdp.Client, resp *resource.DeleteResponse, pollingTimeout *utils.PollingOptions) error {
func deleteEnvironmentWithDiagnosticHandle(environmentName string, ctx context.Context, client *cdp.Client, resp *resource.DeleteResponse, pollingOptions *utils.PollingOptions) error {
params := operations.NewDeleteEnvironmentParamsWithContext(ctx)
params.WithInput(&environmentsmodels.DeleteEnvironmentRequest{EnvironmentName: &environmentName})
_, err := client.Environments.Operations.DeleteEnvironment(params)
Expand All @@ -60,7 +62,10 @@ func deleteEnvironmentWithDiagnosticHandle(environmentName string, ctx context.C
return err
}

err = waitForEnvironmentToBeDeleted(environmentName, timeoutOneHour, client.Environments, ctx, pollingTimeout)
if pollingOptions.Async.ValueBool() {
return nil
}
err = waitForEnvironmentToBeDeleted(environmentName, timeoutOneHour, client.Environments, ctx, pollingOptions)
if err != nil {
utils.AddEnvironmentDiagnosticsError(err, &resp.Diagnostics, "delete Environment")
return err
Expand All @@ -77,7 +82,7 @@ func isEnvNotFoundError(err error) bool {
return false
}

func waitForCreateEnvironmentWithDiagnosticHandle(ctx context.Context, client *cdp.Client, id string, envName string, resp *resource.CreateResponse, options *utils.PollingOptions) (*operations.DescribeEnvironmentOK, error) {
func waitForCreateEnvironmentWithDiagnosticHandle(ctx context.Context, client *cdp.Client, id string, envName string, resp *resource.CreateResponse, options *utils.PollingOptions) (*environmentsmodels.Environment, error) {
if err := waitForEnvironmentToBeAvailable(id, timeoutOneHour, client.Environments, ctx, options); err != nil {
utils.AddEnvironmentDiagnosticsError(err, &resp.Diagnostics, "create Environment failed")
return nil, err
Expand All @@ -101,5 +106,5 @@ func waitForCreateEnvironmentWithDiagnosticHandle(ctx context.Context, client *c
utils.AddEnvironmentDiagnosticsError(err, &resp.Diagnostics, "create Environment failed")
return nil, err
}
return descEnvResp, nil
return descEnvResp.GetPayload().Environment, nil
}
19 changes: 11 additions & 8 deletions resources/environments/resource_aws_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package environments

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"
Expand Down Expand Up @@ -76,12 +77,18 @@ func (r *awsEnvironmentResource) Create(ctx context.Context, req resource.Create
return
}

descEnvResp, err := waitForCreateEnvironmentWithDiagnosticHandle(ctx, r.client, data.ID.ValueString(), data.EnvironmentName.ValueString(), resp, data.PollingOptions)
descEnvResp, err := describeEnvironmentWithDiagnosticHandle(data.EnvironmentName.ValueString(), data.ID.ValueString(), ctx, r.client, &resp.Diagnostics, &resp.State)
if err != nil {
return
}
if !data.PollingOptions.Async.ValueBool() {
descEnvResp, err = waitForCreateEnvironmentWithDiagnosticHandle(ctx, r.client, data.ID.ValueString(), data.EnvironmentName.ValueString(), resp, data.PollingOptions)
if err != nil {
return
}
}

toAwsEnvironmentResource(ctx, utils.LogEnvironmentSilently(ctx, descEnvResp.GetPayload().Environment, describeLogPrefix), &data, data.PollingOptions, &resp.Diagnostics)
toAwsEnvironmentResource(ctx, utils.LogEnvironmentSilently(ctx, descEnvResp, describeLogPrefix), &data, data.PollingOptions, &resp.Diagnostics)
diags = resp.State.Set(ctx, data)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
Expand All @@ -97,7 +104,7 @@ func (r *awsEnvironmentResource) Read(ctx context.Context, req resource.ReadRequ
return
}

env, err := describeEnvironmentWithDiagnosticHandle(state.EnvironmentName.ValueString(), state.ID.ValueString(), ctx, r.client, resp)
env, err := describeEnvironmentWithDiagnosticHandle(state.EnvironmentName.ValueString(), state.ID.ValueString(), ctx, r.client, &resp.Diagnostics, &resp.State)
if err != nil {
return
}
Expand Down Expand Up @@ -203,12 +210,8 @@ func toAwsEnvironmentResource(ctx context.Context, env *environmentsmodels.Envir
model.Status = types.StringPointerValue(env.Status)
model.StatusReason = types.StringValue(env.StatusReason)
if env.Tags != nil {
merged := env.Tags.Defaults
for k, v := range env.Tags.UserDefined {
merged[k] = v
}
var tagDiags diag.Diagnostics
tagMap, tagDiags := types.MapValueFrom(ctx, types.StringType, merged)
tagMap, tagDiags := types.MapValueFrom(ctx, types.StringType, env.Tags.UserDefined)
diags.Append(tagDiags...)
model.Tags = tagMap
}
Expand Down
18 changes: 10 additions & 8 deletions resources/environments/resource_azure_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,18 @@ func (r *azureEnvironmentResource) Create(ctx context.Context, req resource.Crea
return
}

descEnvResp, err := waitForCreateEnvironmentWithDiagnosticHandle(ctx, r.client, data.ID.ValueString(), data.EnvironmentName.ValueString(), resp, data.PollingOptions)
descEnvResp, err := describeEnvironmentWithDiagnosticHandle(data.EnvironmentName.ValueString(), data.ID.ValueString(), ctx, r.client, &resp.Diagnostics, &resp.State)
if err != nil {
return
}
if !data.PollingOptions.Async.ValueBool() {
descEnvResp, err = waitForCreateEnvironmentWithDiagnosticHandle(ctx, r.client, data.ID.ValueString(), data.EnvironmentName.ValueString(), resp, data.PollingOptions)
if err != nil {
return
}
}

toAzureEnvironmentResource(ctx, descEnvResp.GetPayload().Environment, &data, data.PollingOptions, &resp.Diagnostics)
toAzureEnvironmentResource(ctx, descEnvResp, &data, data.PollingOptions, &resp.Diagnostics)
diags = resp.State.Set(ctx, data)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
Expand All @@ -99,7 +105,7 @@ func (r *azureEnvironmentResource) Read(ctx context.Context, req resource.ReadRe
return
}

descEnvResp, err := describeEnvironmentWithDiagnosticHandle(state.EnvironmentName.ValueString(), state.ID.ValueString(), ctx, r.client, resp)
descEnvResp, err := describeEnvironmentWithDiagnosticHandle(state.EnvironmentName.ValueString(), state.ID.ValueString(), ctx, r.client, &resp.Diagnostics, &resp.State)
if err != nil {
return
}
Expand Down Expand Up @@ -210,11 +216,7 @@ func toAzureEnvironmentResource(ctx context.Context, env *environmentsmodels.Env
model.Status = types.StringPointerValue(env.Status)
model.StatusReason = types.StringValue(env.StatusReason)
if env.Tags != nil {
merged := env.Tags.Defaults
for k, v := range env.Tags.UserDefined {
merged[k] = v
}
tagMap, tagDiags := types.MapValueFrom(ctx, types.StringType, merged)
tagMap, tagDiags := types.MapValueFrom(ctx, types.StringType, env.Tags.UserDefined)
diags.Append(tagDiags...)
model.Tags = tagMap
}
Expand Down
3 changes: 3 additions & 0 deletions resources/environments/resource_azure_environment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func createRawAzureEnvironmentResource() tftypes.Value {
"crn": tftypes.String,
"polling_options": tftypes.Object{
AttributeTypes: map[string]tftypes.Type{
"async": tftypes.Bool,
"polling_timeout": tftypes.Number,
},
},
Expand Down Expand Up @@ -118,9 +119,11 @@ func createRawAzureEnvironmentResource() tftypes.Value {
"crn": tftypes.NewValue(tftypes.String, ""),
"polling_options": tftypes.NewValue(tftypes.Object{
AttributeTypes: map[string]tftypes.Type{
"async": tftypes.Bool,
"polling_timeout": tftypes.Number,
},
}, map[string]tftypes.Value{
"async": tftypes.NewValue(tftypes.Bool, false),
"polling_timeout": tftypes.NewValue(tftypes.Number, 100),
}),
"status_reason": tftypes.NewValue(tftypes.String, ""),
Expand Down
13 changes: 10 additions & 3 deletions resources/environments/resource_gcp_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package environments

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-log/tflog"

Expand Down Expand Up @@ -70,12 +71,18 @@ func (r *gcpEnvironmentResource) Create(ctx context.Context, req resource.Create
return
}

descEnvResp, err := waitForCreateEnvironmentWithDiagnosticHandle(ctx, r.client, data.ID.ValueString(), data.EnvironmentName.ValueString(), resp, data.PollingOptions)
descEnvResp, err := describeEnvironmentWithDiagnosticHandle(data.EnvironmentName.ValueString(), data.ID.ValueString(), ctx, r.client, &resp.Diagnostics, &resp.State)
if err != nil {
return
}
if !data.PollingOptions.Async.ValueBool() {
descEnvResp, err = waitForCreateEnvironmentWithDiagnosticHandle(ctx, r.client, data.ID.ValueString(), data.EnvironmentName.ValueString(), resp, data.PollingOptions)
if err != nil {
return
}
}

toGcpEnvironmentResource(ctx, utils.LogEnvironmentSilently(ctx, descEnvResp.GetPayload().Environment, describeLogPrefix), &data, data.PollingOptions, &resp.Diagnostics)
toGcpEnvironmentResource(ctx, utils.LogEnvironmentSilently(ctx, descEnvResp, describeLogPrefix), &data, data.PollingOptions, &resp.Diagnostics)
diags = resp.State.Set(ctx, data)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
Expand All @@ -91,7 +98,7 @@ func (r *gcpEnvironmentResource) Read(ctx context.Context, req resource.ReadRequ
return
}

descEnvResp, err := describeEnvironmentWithDiagnosticHandle(state.EnvironmentName.ValueString(), state.ID.ValueString(), ctx, r.client, resp)
descEnvResp, err := describeEnvironmentWithDiagnosticHandle(state.EnvironmentName.ValueString(), state.ID.ValueString(), ctx, r.client, &resp.Diagnostics, &resp.State)
if err != nil {
return
}
Expand Down
Loading
Loading