Skip to content

Commit

Permalink
added all crud methods for function resource
Browse files Browse the repository at this point in the history
  • Loading branch information
dgomez04 committed Nov 2, 2024
1 parent 20b2a4e commit 2213438
Showing 1 changed file with 115 additions and 18 deletions.
133 changes: 115 additions & 18 deletions internal/providers/pluginfw/resources/catalog/resource_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ package catalog

import (
"context"
"fmt"
"time"

"github.com/databricks/databricks-sdk-go"
"github.com/databricks/databricks-sdk-go/apierr"
"github.com/databricks/databricks-sdk-go/retries"
"github.com/databricks/databricks-sdk-go/service/catalog"
"github.com/databricks/terraform-provider-databricks/common"
pluginfwcommon "github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/common"
Expand All @@ -12,6 +16,7 @@ import (
"github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/tfschema"
"github.com/databricks/terraform-provider-databricks/internal/service/catalog_tf"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
)
Expand All @@ -24,6 +29,28 @@ func ResourceFunction() resource.Resource {
return &FunctionResource{}
}

func waitForFunction(ctx context.Context, w *databricks.WorkspaceClient, funcInfo *catalog.FunctionInfo) diag.Diagnostics {
const timeout = 5 * time.Minute

result, err := retries.Poll[catalog.FunctionInfo](ctx, timeout, func() (*catalog.FunctionInfo, *retries.Err) {
attempt, err := w.Functions.GetByName(ctx, funcInfo.FullName)
if err != nil {
if apierr.IsMissing(err) {
return nil, retries.Continue(fmt.Errorf("function %s is not yet available", funcInfo.FullName))
}
return nil, retries.Halt(fmt.Errorf("failed to get function: %s", err))
}
return attempt, nil
})

if err != nil {
return diag.Diagnostics{diag.NewErrorDiagnostic("failed to create function", err.Error())}
}

*funcInfo = *result
return nil
}

type FunctionResource struct {
Client *common.DatabricksClient
}
Expand All @@ -32,9 +59,25 @@ func (r *FunctionResource) Metadata(ctx context.Context, req resource.MetadataRe
resp.TypeName = pluginfwcommon.GetDatabricksProductionName(resourceName)
}

// TODO: Update as needed to fit the requirements of the resource.
func (r *FunctionResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
attrs, blocks := tfschema.ResourceStructToSchemaMap(catalog_tf.FunctionInfo{}, nil)
attrs, blocks := tfschema.ResourceStructToSchemaMap(catalog_tf.FunctionInfo{}, func(c tfschema.CustomizableSchema) tfschema.CustomizableSchema {
c.SetRequired("name")
c.SetRequired("catalog_name")
c.SetRequired("schema_name")
c.SetRequired("input_params")
c.SetRequired("data_type")
c.SetRequired("routine_body")
c.SetRequired("routine_defintion")
c.SetRequired("language")

c.SetReadOnly("full_name")
c.SetReadOnly("created_at")
c.SetReadOnly("created_by")
c.SetReadOnly("updated_at")
c.SetReadOnly("updated_by")

return c
})

resp.Schema = schema.Schema{
Description: "Terraform schema for Databricks Function",
Expand All @@ -49,30 +92,67 @@ func (r *FunctionResource) Configure(ctx context.Context, req resource.Configure
}
}

func AppendDiagAndCheckErrors(resp *diag.Diagnostics, diags diag.Diagnostics) bool {
resp.Append(diags...)
return resp.HasError()
func (r *FunctionResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
resource.ImportStatePassthroughID(ctx, path.Root("full_name"), req, resp)
}

func (r *FunctionResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
ctx = pluginfwcontext.SetUserAgentInResourceContext(ctx, resourceName)
w, diags := r.Client.GetWorkspaceClient()
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

var planFunc catalog_tf.FunctionInfo
resp.Diagnostics.Append(req.Plan.Get(ctx, &planFunc)...)
if resp.Diagnostics.HasError() {
return
}

var createReq catalog.CreateFunctionRequest

resp.Diagnostics.Append(converters.TfSdkToGoSdkStruct(ctx, planFunc, &createReq)...)
if resp.Diagnostics.HasError() {
return
}

funcInfo, err := w.Functions.Create(ctx, createReq)
if err != nil {
resp.Diagnostics.AddError("failed to create function", err.Error())
}

resp.Diagnostics.Append(waitForFunction(ctx, w, funcInfo)...)
if resp.Diagnostics.HasError() {
return
}

resp.Diagnostics.Append(converters.GoSdkToTfSdkStruct(ctx, funcInfo, &planFunc)...)
if resp.Diagnostics.HasError() {
return
}

resp.Diagnostics.Append(resp.State.Set(ctx, planFunc)...)
}

func (r *FunctionResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
ctx = pluginfwcontext.SetUserAgentInResourceContext(ctx, resourceName)
w, diags := r.Client.GetWorkspaceClient()
if AppendDiagAndCheckErrors(&resp.Diagnostics, diags) {
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

var planFunc catalog_tf.FunctionInfo
if AppendDiagAndCheckErrors(&resp.Diagnostics, req.Plan.Get(ctx, &planFunc)) {
resp.Diagnostics.Append(req.Plan.Get(ctx, &planFunc)...)
if resp.Diagnostics.HasError() {
return
}

var updateReq catalog.UpdateFunction

if AppendDiagAndCheckErrors(&resp.Diagnostics, converters.TfSdkToGoSdkStruct(ctx, planFunc, &updateReq)) {
resp.Diagnostics.Append(converters.TfSdkToGoSdkStruct(ctx, planFunc, &updateReq)...)
if resp.Diagnostics.HasError() {
return
}

Expand All @@ -81,25 +161,27 @@ func (r *FunctionResource) Update(ctx context.Context, req resource.UpdateReques
resp.Diagnostics.AddError("failed to update function", err.Error())
}

if AppendDiagAndCheckErrors(&resp.Diagnostics, converters.GoSdkToTfSdkStruct(ctx, funcInfo, &planFunc)) {
resp.Diagnostics.Append(converters.GoSdkToTfSdkStruct(ctx, funcInfo, &planFunc)...)
if resp.Diagnostics.HasError() {
return
}

if AppendDiagAndCheckErrors(&resp.Diagnostics, resp.State.Set(ctx, funcInfo)) {
return
}
resp.Diagnostics.Append(resp.State.Set(ctx, planFunc)...)
}

func (r *FunctionResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
ctx = pluginfwcontext.SetUserAgentInResourceContext(ctx, resourceName)

w, diags := r.Client.GetWorkspaceClient()
if AppendDiagAndCheckErrors(&resp.Diagnostics, diags) {
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

var stateFunc catalog_tf.FunctionInfo
if AppendDiagAndCheckErrors(&resp.Diagnostics, req.State.Get(ctx, &stateFunc)) {

resp.Diagnostics.Append(req.State.Get(ctx, &stateFunc)...)
if resp.Diagnostics.HasError() {
return
}

Expand All @@ -115,15 +197,30 @@ func (r *FunctionResource) Read(ctx context.Context, req resource.ReadRequest, r
return
}

if AppendDiagAndCheckErrors(&resp.Diagnostics, converters.GoSdkToTfSdkStruct(ctx, funcInfo, &stateFunc)) {
resp.Diagnostics.Append(converters.GoSdkToTfSdkStruct(ctx, funcInfo, &stateFunc)...)
if resp.Diagnostics.HasError() {
return
}

if AppendDiagAndCheckErrors(&resp.Diagnostics, resp.State.Set(ctx, stateFunc)) {
return
}
resp.Diagnostics.Append(resp.State.Set(ctx, stateFunc)...)
}

func (r *FunctionResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
ctx = pluginfwcontext.SetUserAgentInResourceContext(ctx, resourceName)
w, diags := r.Client.GetWorkspaceClient()
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

var deleteReq catalog_tf.DeleteFunctionRequest
resp.Diagnostics.Append(req.State.GetAttribute(ctx, path.Root("full_name"), &deleteReq.Name)...)
if resp.Diagnostics.HasError() {
return
}

err := w.Functions.DeleteByName(ctx, deleteReq.Name.ValueString())
if err != nil && !apierr.IsMissing(err) {
resp.Diagnostics.AddError("failed to delete function", err.Error())
}
}

0 comments on commit 2213438

Please sign in to comment.