From 804899f72077726d91bb9a7ec6f070b44fed78a6 Mon Sep 17 00:00:00 2001 From: Dana Fallon <8871189+danafallon@users.noreply.github.com> Date: Fri, 26 Jul 2024 17:26:46 -0700 Subject: [PATCH 1/3] Implement create destination --- examples/deployments/main.tf | 8 +-- internal/provider/destination_resource.go | 70 +++++++++++++++++++---- 2 files changed, 62 insertions(+), 16 deletions(-) diff --git a/examples/deployments/main.tf b/examples/deployments/main.tf index 317d02d..1ed4c6c 100644 --- a/examples/deployments/main.tf +++ b/examples/deployments/main.tf @@ -10,10 +10,10 @@ provider "artie" { endpoint = "http://0.0.0.0:8000" } -import { - to = artie_destination.bigquery - id = "fa7d4efc-3957-41e5-b29c-66e2d49bffde" -} +# import { +# to = artie_destination.bigquery +# id = "fa7d4efc-3957-41e5-b29c-66e2d49bffde" +# } resource "artie_destination" "bigquery" { name = "BigQuery" diff --git a/internal/provider/destination_resource.go b/internal/provider/destination_resource.go index 794d208..bfde201 100644 --- a/internal/provider/destination_resource.go +++ b/internal/provider/destination_resource.go @@ -1,6 +1,7 @@ package provider import ( + "bytes" "context" "encoding/json" "fmt" @@ -11,7 +12,9 @@ import ( "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-log/tflog" ) @@ -47,16 +50,16 @@ func (r *DestinationResource) Schema(ctx context.Context, req resource.SchemaReq "config": schema.SingleNestedAttribute{ Required: true, Attributes: map[string]schema.Attribute{ - "host": schema.StringAttribute{Optional: true}, - "port": schema.Int64Attribute{Optional: true}, - "endpoint": schema.StringAttribute{Optional: true}, - "username": schema.StringAttribute{Optional: true}, - "gcp_project_id": schema.StringAttribute{Optional: true}, - "gcp_location": schema.StringAttribute{Optional: true}, - "aws_access_key_id": schema.StringAttribute{Optional: true}, - "aws_region": schema.StringAttribute{Optional: true}, - "snowflake_account_url": schema.StringAttribute{Optional: true}, - "snowflake_virtual_dwh": schema.StringAttribute{Optional: true}, + "host": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("")}, + "port": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(0)}, + "endpoint": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("")}, + "username": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("")}, + "gcp_project_id": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("")}, + "gcp_location": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("")}, + "aws_access_key_id": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("")}, + "aws_region": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("")}, + "snowflake_account_url": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("")}, + "snowflake_virtual_dwh": schema.StringAttribute{Optional: true, Computed: true, Default: stringdefault.StaticString("")}, }, }, }, @@ -91,7 +94,50 @@ func (r *DestinationResource) Create(ctx context.Context, req resource.CreateReq return } - // TODO implement Create + destModel := models.DestinationResourceToAPIModel(data) + payload := map[string]any{ + "name": destModel.Name, + "label": destModel.Label, + "sharedConfig": destModel.Config, + } + if destModel.SSHTunnelUUID != "" { + payload["sshTunnelUUID"] = destModel.SSHTunnelUUID + } + payloadBytes, err := json.Marshal(payload) + if err != nil { + resp.Diagnostics.AddError("Unable to Create Destination", err.Error()) + return + } + + url := fmt.Sprintf("%s/destinations", r.endpoint) + ctx = tflog.SetField(ctx, "url", url) + ctx = tflog.SetField(ctx, "payload", string(payloadBytes)) + tflog.Info(ctx, "Creating destination via API") + + apiReq, err := http.NewRequest("POST", url, bytes.NewReader(payloadBytes)) + if err != nil { + resp.Diagnostics.AddError("Unable to Create Destination", err.Error()) + return + } + + bodyBytes, err := r.handleAPIRequest(apiReq) + if err != nil { + resp.Diagnostics.AddError("Unable to Create Destination", err.Error()) + return + } + + ctx = tflog.SetField(ctx, "response", string(bodyBytes)) + tflog.Info(ctx, "Created destination") + + var destination models.DestinationAPIModel + err = json.Unmarshal(bodyBytes, &destination) + if err != nil { + resp.Diagnostics.AddError("Unable to Create Destination", err.Error()) + return + } + + // Translate API response into Terraform state + models.DestinationAPIToResourceModel(destination, &data) // Save updated data into Terraform state resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) @@ -107,7 +153,7 @@ func (r *DestinationResource) Read(ctx context.Context, req resource.ReadRequest url := fmt.Sprintf("%s/destinations/%s", r.endpoint, data.UUID.ValueString()) ctx = tflog.SetField(ctx, "url", url) - tflog.Info(ctx, "Reading Destination") + tflog.Info(ctx, "Reading destination from API") apiReq, err := http.NewRequest("GET", url, nil) if err != nil { resp.Diagnostics.AddError("Unable to Read Destination", err.Error()) From ea6dc11b60800227015ba0b19eb5b4c443154c3d Mon Sep 17 00:00:00 2001 From: Dana Fallon <8871189+danafallon@users.noreply.github.com> Date: Fri, 26 Jul 2024 17:32:18 -0700 Subject: [PATCH 2/3] Make importing work again --- examples/deployments/main.tf | 8 ++++---- internal/provider/destination_resource.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/deployments/main.tf b/examples/deployments/main.tf index 1ed4c6c..317d02d 100644 --- a/examples/deployments/main.tf +++ b/examples/deployments/main.tf @@ -10,10 +10,10 @@ provider "artie" { endpoint = "http://0.0.0.0:8000" } -# import { -# to = artie_destination.bigquery -# id = "fa7d4efc-3957-41e5-b29c-66e2d49bffde" -# } +import { + to = artie_destination.bigquery + id = "fa7d4efc-3957-41e5-b29c-66e2d49bffde" +} resource "artie_destination" "bigquery" { name = "BigQuery" diff --git a/internal/provider/destination_resource.go b/internal/provider/destination_resource.go index bfde201..be4f3f2 100644 --- a/internal/provider/destination_resource.go +++ b/internal/provider/destination_resource.go @@ -46,7 +46,7 @@ func (r *DestinationResource) Schema(ctx context.Context, req resource.SchemaReq "ssh_tunnel_uuid": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, "name": schema.StringAttribute{Required: true}, "label": schema.StringAttribute{Optional: true}, - "last_updated_at": schema.StringAttribute{Computed: true}, + "last_updated_at": schema.StringAttribute{Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}}, "config": schema.SingleNestedAttribute{ Required: true, Attributes: map[string]schema.Attribute{ From 479e08f79e88fba1018193b7ca9eac4b1889284e Mon Sep 17 00:00:00 2001 From: Dana Fallon <8871189+danafallon@users.noreply.github.com> Date: Fri, 26 Jul 2024 17:35:21 -0700 Subject: [PATCH 3/3] Reference destination resource in deployment config --- examples/deployments/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/deployments/main.tf b/examples/deployments/main.tf index 317d02d..57e60e4 100644 --- a/examples/deployments/main.tf +++ b/examples/deployments/main.tf @@ -60,7 +60,7 @@ resource "artie_deployment" "example" { } ] } - destination_uuid = "fa7d4efc-3957-41e5-b29c-66e2d49bffde" // artie_destination.bigquery.uuid + destination_uuid = artie_destination.bigquery.uuid destination_config = { dataset = "customers" }