From af4fb226f983f88bf87a28b0b497c444680b09ba Mon Sep 17 00:00:00 2001 From: Artur Sawicki Date: Thu, 12 Dec 2024 12:51:33 +0100 Subject: [PATCH] Add missing to procedure --- .../function_describe_snowflake_ext.go | 8 +- .../procedure_describe_snowflake_ext.go | 8 +- .../config/model/function_java_model_ext.go | 2 +- .../config/model/procedure_java_model_ext.go | 51 +++++++++++ .../function_and_procedure_commons.go | 48 ++++++++++ pkg/resources/function_commons.go | 48 ---------- pkg/resources/function_java.go | 2 +- pkg/resources/procedure_commons.go | 16 +++- pkg/resources/procedure_java.go | 57 ++++++++---- .../procedure_java_acceptance_test.go | 89 ++++++++++++++++++- pkg/sdk/procedures_ext.go | 1 - 11 files changed, 245 insertions(+), 85 deletions(-) diff --git a/pkg/acceptance/bettertestspoc/assert/objectassert/function_describe_snowflake_ext.go b/pkg/acceptance/bettertestspoc/assert/objectassert/function_describe_snowflake_ext.go index 92bf1c16e1..b00dad3d3c 100644 --- a/pkg/acceptance/bettertestspoc/assert/objectassert/function_describe_snowflake_ext.go +++ b/pkg/acceptance/bettertestspoc/assert/objectassert/function_describe_snowflake_ext.go @@ -500,13 +500,11 @@ func (f *FunctionDetailsAssert) ContainsExactlySecrets(secrets map[string]sdk.Sc for k, v := range secrets { if s, ok := o.NormalizedSecrets[k]; !ok { return fmt.Errorf("expected normalized secrets to have a secret associated with key %s", k) - } else { - if s.FullyQualifiedName() != v.FullyQualifiedName() { - return fmt.Errorf("expected secret with key %s to have id %s, got %s", k, v.FullyQualifiedName(), s.FullyQualifiedName()) - } + } else if s.FullyQualifiedName() != v.FullyQualifiedName() { + return fmt.Errorf("expected secret with key %s to have id %s, got %s", k, v.FullyQualifiedName(), s.FullyQualifiedName()) } } - for k, _ := range o.NormalizedSecrets { + for k := range o.NormalizedSecrets { if _, ok := secrets[k]; !ok { return fmt.Errorf("normalized secrets have unexpected key: %s", k) } diff --git a/pkg/acceptance/bettertestspoc/assert/objectassert/procedure_describe_snowflake_ext.go b/pkg/acceptance/bettertestspoc/assert/objectassert/procedure_describe_snowflake_ext.go index ef04c3abc2..962d34f2d6 100644 --- a/pkg/acceptance/bettertestspoc/assert/objectassert/procedure_describe_snowflake_ext.go +++ b/pkg/acceptance/bettertestspoc/assert/objectassert/procedure_describe_snowflake_ext.go @@ -486,13 +486,11 @@ func (f *ProcedureDetailsAssert) ContainsExactlySecrets(secrets map[string]sdk.S for k, v := range secrets { if s, ok := o.NormalizedSecrets[k]; !ok { return fmt.Errorf("expected normalized secrets to have a secret associated with key %s", k) - } else { - if s.FullyQualifiedName() != v.FullyQualifiedName() { - return fmt.Errorf("expected secret with key %s to have id %s, got %s", k, v.FullyQualifiedName(), s.FullyQualifiedName()) - } + } else if s.FullyQualifiedName() != v.FullyQualifiedName() { + return fmt.Errorf("expected secret with key %s to have id %s, got %s", k, v.FullyQualifiedName(), s.FullyQualifiedName()) } } - for k, _ := range o.NormalizedSecrets { + for k := range o.NormalizedSecrets { if _, ok := secrets[k]; !ok { return fmt.Errorf("normalized secrets have unexpected key: %s", k) } diff --git a/pkg/acceptance/bettertestspoc/config/model/function_java_model_ext.go b/pkg/acceptance/bettertestspoc/config/model/function_java_model_ext.go index 5f106b6ab1..0174c4dc10 100644 --- a/pkg/acceptance/bettertestspoc/config/model/function_java_model_ext.go +++ b/pkg/acceptance/bettertestspoc/config/model/function_java_model_ext.go @@ -110,7 +110,7 @@ func (f *FunctionJavaModel) WithExternalAccessIntegrations(ids ...sdk.AccountObj } func (f *FunctionJavaModel) WithSecrets(secrets map[string]sdk.SchemaObjectIdentifier) *FunctionJavaModel { - var objects []tfconfig.Variable + objects := make([]tfconfig.Variable, 0) for k, v := range secrets { objects = append(objects, tfconfig.ObjectVariable( map[string]tfconfig.Variable{ diff --git a/pkg/acceptance/bettertestspoc/config/model/procedure_java_model_ext.go b/pkg/acceptance/bettertestspoc/config/model/procedure_java_model_ext.go index cb6779784c..b8a1602f79 100644 --- a/pkg/acceptance/bettertestspoc/config/model/procedure_java_model_ext.go +++ b/pkg/acceptance/bettertestspoc/config/model/procedure_java_model_ext.go @@ -3,6 +3,8 @@ package model import ( "encoding/json" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/collections" + tfconfig "github.com/hashicorp/terraform-plugin-testing/config" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" @@ -77,6 +79,55 @@ func (f *ProcedureJavaModel) WithImport(stageLocation string, pathOnStage string ) } +func (f *ProcedureJavaModel) WithImports(imports ...sdk.NormalizedPath) *ProcedureJavaModel { + return f.WithImportsValue( + tfconfig.SetVariable( + collections.Map(imports, func(imp sdk.NormalizedPath) tfconfig.Variable { + return tfconfig.ObjectVariable( + map[string]tfconfig.Variable{ + "stage_location": tfconfig.StringVariable(imp.StageLocation), + "path_on_stage": tfconfig.StringVariable(imp.PathOnStage), + }, + ) + })..., + ), + ) +} + +func (f *ProcedureJavaModel) WithPackages(pkgs ...string) *ProcedureJavaModel { + return f.WithPackagesValue( + tfconfig.SetVariable( + collections.Map(pkgs, func(pkg string) tfconfig.Variable { return tfconfig.StringVariable(pkg) })..., + ), + ) +} + +func (f *ProcedureJavaModel) WithExternalAccessIntegrations(ids ...sdk.AccountObjectIdentifier) *ProcedureJavaModel { + return f.WithExternalAccessIntegrationsValue( + tfconfig.SetVariable( + collections.Map(ids, func(id sdk.AccountObjectIdentifier) tfconfig.Variable { return tfconfig.StringVariable(id.Name()) })..., + ), + ) +} + +func (f *ProcedureJavaModel) WithSecrets(secrets map[string]sdk.SchemaObjectIdentifier) *ProcedureJavaModel { + objects := make([]tfconfig.Variable, 0) + for k, v := range secrets { + objects = append(objects, tfconfig.ObjectVariable( + map[string]tfconfig.Variable{ + "secret_variable_name": tfconfig.StringVariable(k), + "secret_id": tfconfig.StringVariable(v.FullyQualifiedName()), + }, + )) + } + + return f.WithSecretsValue( + tfconfig.SetVariable( + objects..., + ), + ) +} + func (f *ProcedureJavaModel) WithTargetPathParts(stageLocation string, pathOnStage string) *ProcedureJavaModel { return f.WithTargetPathValue( tfconfig.ObjectVariable( diff --git a/pkg/resources/function_and_procedure_commons.go b/pkg/resources/function_and_procedure_commons.go index 0a7f3acdb0..213217e968 100644 --- a/pkg/resources/function_and_procedure_commons.go +++ b/pkg/resources/function_and_procedure_commons.go @@ -67,3 +67,51 @@ func readFunctionOrProcedureTargetPath(d *schema.ResourceData, normalizedPath *s } return d.Set("target_path", tp) } + +func setExternalAccessIntegrationsInBuilder[T any](d *schema.ResourceData, setIntegrations func([]sdk.AccountObjectIdentifier) T) error { + integrations, err := parseExternalAccessIntegrationsCommon(d) + if err != nil { + return err + } + setIntegrations(integrations) + return nil +} + +func setSecretsInBuilder[T any](d *schema.ResourceData, setSecrets func([]sdk.SecretReference) T) error { + secrets, err := parseSecretsCommon(d) + if err != nil { + return err + } + setSecrets(secrets) + return nil +} + +func parseExternalAccessIntegrationsCommon(d *schema.ResourceData) ([]sdk.AccountObjectIdentifier, error) { + integrations := make([]sdk.AccountObjectIdentifier, 0) + if v, ok := d.GetOk("external_access_integrations"); ok { + for _, i := range v.(*schema.Set).List() { + id, err := sdk.ParseAccountObjectIdentifier(i.(string)) + if err != nil { + return nil, err + } + integrations = append(integrations, id) + } + } + return integrations, nil +} + +func parseSecretsCommon(d *schema.ResourceData) ([]sdk.SecretReference, error) { + secretReferences := make([]sdk.SecretReference, 0) + if v, ok := d.GetOk("secrets"); ok { + for _, s := range v.(*schema.Set).List() { + name := s.(map[string]any)["secret_variable_name"].(string) + idRaw := s.(map[string]any)["secret_id"].(string) + id, err := sdk.ParseSchemaObjectIdentifier(idRaw) + if err != nil { + return nil, err + } + secretReferences = append(secretReferences, sdk.SecretReference{VariableName: name, Name: id}) + } + } + return secretReferences, nil +} diff --git a/pkg/resources/function_commons.go b/pkg/resources/function_commons.go index 526f090f8c..7dddd097e7 100644 --- a/pkg/resources/function_commons.go +++ b/pkg/resources/function_commons.go @@ -450,36 +450,6 @@ func parseFunctionPackagesCommon(d *schema.ResourceData) ([]sdk.FunctionPackageR return packages, nil } -func parseExternalAccessIntegrationsCommon(d *schema.ResourceData) ([]sdk.AccountObjectIdentifier, error) { - integrations := make([]sdk.AccountObjectIdentifier, 0) - if v, ok := d.GetOk("external_access_integrations"); ok { - for _, i := range v.(*schema.Set).List() { - id, err := sdk.ParseAccountObjectIdentifier(i.(string)) - if err != nil { - return nil, err - } - integrations = append(integrations, id) - } - } - return integrations, nil -} - -func parseSecretsCommon(d *schema.ResourceData) ([]sdk.SecretReference, error) { - secretReferences := make([]sdk.SecretReference, 0) - if v, ok := d.GetOk("secrets"); ok { - for _, s := range v.(*schema.Set).List() { - name := s.(map[string]any)["secret_variable_name"].(string) - idRaw := s.(map[string]any)["secret_id"].(string) - id, err := sdk.ParseSchemaObjectIdentifier(idRaw) - if err != nil { - return nil, err - } - secretReferences = append(secretReferences, sdk.SecretReference{VariableName: name, Name: id}) - } - } - return secretReferences, nil -} - func parseFunctionTargetPathCommon(d *schema.ResourceData) (string, error) { var tp string if v, ok := d.GetOk("target_path"); ok { @@ -530,24 +500,6 @@ func setFunctionPackagesInBuilder[T any](d *schema.ResourceData, setPackages fun return nil } -func setExternalAccessIntegrationsInBuilder[T any](d *schema.ResourceData, setIntegrations func([]sdk.AccountObjectIdentifier) T) error { - integrations, err := parseExternalAccessIntegrationsCommon(d) - if err != nil { - return err - } - setIntegrations(integrations) - return nil -} - -func setSecretsInBuilder[T any](d *schema.ResourceData, setSecrets func([]sdk.SecretReference) T) error { - secrets, err := parseSecretsCommon(d) - if err != nil { - return err - } - setSecrets(secrets) - return nil -} - func setFunctionTargetPathInBuilder[T any](d *schema.ResourceData, setTargetPath func(string) T) error { tp, err := parseFunctionTargetPathCommon(d) if err != nil { diff --git a/pkg/resources/function_java.go b/pkg/resources/function_java.go index 31664b5416..e085fc0c97 100644 --- a/pkg/resources/function_java.go +++ b/pkg/resources/function_java.go @@ -184,7 +184,7 @@ func UpdateContextFunctionJava(ctx context.Context, d *schema.ResourceData, meta func() error { if d.HasChange("external_access_integrations") { return setExternalAccessIntegrationsInBuilder(d, func(references []sdk.AccountObjectIdentifier) any { - if references == nil || len(references) == 0 { + if len(references) == 0 { return unsetRequest.WithExternalAccessIntegrations(true) } else { return setRequest.WithExternalAccessIntegrations(references) diff --git a/pkg/resources/procedure_commons.go b/pkg/resources/procedure_commons.go index 759f44f878..addb4f3c30 100644 --- a/pkg/resources/procedure_commons.go +++ b/pkg/resources/procedure_commons.go @@ -256,9 +256,8 @@ func procedureBaseSchema() map[string]schema.Schema { ForceNew: true, }, "comment": { - Type: schema.TypeString, - Optional: true, - // TODO [SNOW-1348103]: handle dynamic comment - this is a workaround for now + Type: schema.TypeString, + Optional: true, Default: "user-defined procedure", Description: "Specifies a comment for the procedure.", }, @@ -307,7 +306,6 @@ func procedureBaseSchema() map[string]schema.Schema { ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](), }, Optional: true, - ForceNew: true, Description: "The names of [external access integrations](https://docs.snowflake.com/en/sql-reference/sql/create-external-access-integration) needed in order for this procedure’s handler code to access external networks. An external access integration specifies [network rules](https://docs.snowflake.com/en/sql-reference/sql/create-network-rule) and [secrets](https://docs.snowflake.com/en/sql-reference/sql/create-secret) that specify external locations and credentials (if any) allowed for use by handler code when making requests of an external network, such as an external REST API.", }, "secrets": { @@ -486,6 +484,16 @@ func parseProcedureImportsCommon(d *schema.ResourceData) ([]sdk.ProcedureImportR return imports, nil } +func parseProceduresPackagesCommon(d *schema.ResourceData) ([]sdk.ProcedurePackageRequest, error) { + packages := make([]sdk.ProcedurePackageRequest, 0) + if v, ok := d.GetOk("packages"); ok { + for _, pkg := range v.(*schema.Set).List() { + packages = append(packages, *sdk.NewProcedurePackageRequest(pkg.(string))) + } + } + return packages, nil +} + func parseProcedureTargetPathCommon(d *schema.ResourceData) (string, error) { var tp string if v, ok := d.GetOk("target_path"); ok { diff --git a/pkg/resources/procedure_java.go b/pkg/resources/procedure_java.go index bc4f417144..04fcb0cf1a 100644 --- a/pkg/resources/procedure_java.go +++ b/pkg/resources/procedure_java.go @@ -62,8 +62,12 @@ func CreateContextProcedureJava(ctx context.Context, d *schema.ResourceData, met } handler := d.Get("handler").(string) runtimeVersion := d.Get("runtime_version").(string) - // TODO [this PR]: handle real packages - packages := []sdk.ProcedurePackageRequest{*sdk.NewProcedurePackageRequest("com.snowflake:snowpark:1.14.0")} + + packages, err := parseProceduresPackagesCommon(d) + if err != nil { + return diag.FromErr(err) + } + packages = append(packages, *sdk.NewProcedurePackageRequest(fmt.Sprintf(`%s%s`, sdk.JavaSnowparkPackageString, d.Get("snowpark_package").(string)))) argumentDataTypes := collections.Map(argumentRequests, func(r sdk.ProcedureArgumentRequest) datatypes.DataType { return r.ArgDataType }) id := sdk.NewSchemaObjectIdentifierWithArgumentsNormalized(database, sc, name, argumentDataTypes...) @@ -73,12 +77,10 @@ func CreateContextProcedureJava(ctx context.Context, d *schema.ResourceData, met errs := errors.Join( booleanStringAttributeCreateBuilder(d, "is_secure", request.WithSecure), attributeMappedValueCreateBuilder[string](d, "null_input_behavior", request.WithNullInputBehavior, sdk.ToNullInputBehavior), - // TODO [SNOW-1348103]: handle the rest of the attributes - // comment + stringAttributeCreateBuilder(d, "comment", request.WithComment), setProcedureImportsInBuilder(d, request.WithImports), - // packages - // external_access_integrations - // secrets + setExternalAccessIntegrationsInBuilder(d, request.WithExternalAccessIntegrations), + setSecretsInBuilder(d, request.WithSecrets), setProcedureTargetPathInBuilder(d, request.WithTargetPath), stringAttributeCreateBuilder(d, "procedure_definition", request.WithProcedureDefinitionWrapped), ) @@ -122,18 +124,18 @@ func ReadContextProcedureJava(ctx context.Context, d *schema.ResourceData, meta // TODO [SNOW-1348103]: handle setting state to value from config errs := errors.Join( - // TODO [SNOW-1348103]: set the rest of the fields // not reading is_secure on purpose (handled as external change to show output) readFunctionOrProcedureArguments(d, allProcedureDetails.procedureDetails.NormalizedArguments), d.Set("return_type", allProcedureDetails.procedureDetails.ReturnDataType.ToSql()), // not reading null_input_behavior on purpose (handled as external change to show output) setRequiredFromStringPtr(d, "runtime_version", allProcedureDetails.procedureDetails.RuntimeVersion), - // comment + d.Set("comment", allProcedureDetails.procedure.Description), readFunctionOrProcedureImports(d, allProcedureDetails.procedureDetails.NormalizedImports), - // packages + d.Set("packages", allProcedureDetails.procedureDetails.NormalizedPackages), + d.Set("snowpark_package", allProcedureDetails.procedureDetails.SnowparkVersion), setRequiredFromStringPtr(d, "handler", allProcedureDetails.procedureDetails.Handler), - // external_access_integrations - // secrets + readFunctionOrProcedureExternalAccessIntegrations(d, allProcedureDetails.procedureDetails.NormalizedExternalAccessIntegrations), + readFunctionOrProcedureSecrets(d, allProcedureDetails.procedureDetails.NormalizedSecrets), readFunctionOrProcedureTargetPath(d, allProcedureDetails.procedureDetails.NormalizedTargetPath), setOptionalFromStringPtr(d, "procedure_definition", allProcedureDetails.procedureDetails.Body), d.Set("procedure_language", allProcedureDetails.procedureDetails.Language), @@ -173,11 +175,32 @@ func UpdateContextProcedureJava(ctx context.Context, d *schema.ResourceData, met setRequest := sdk.NewProcedureSetRequest() unsetRequest := sdk.NewProcedureUnsetRequest() - // TODO [SNOW-1348103]: handle all updates - // secure - // external access integration - // secrets - // comment + err = errors.Join( + stringAttributeUpdate(d, "comment", &setRequest.Comment, &unsetRequest.Comment), + func() error { + if d.HasChange("secrets") { + return setSecretsInBuilder(d, func(references []sdk.SecretReference) *sdk.ProcedureSetRequest { + return setRequest.WithSecretsList(sdk.SecretsListRequest{SecretsList: references}) + }) + } + return nil + }(), + func() error { + if d.HasChange("external_access_integrations") { + return setExternalAccessIntegrationsInBuilder(d, func(references []sdk.AccountObjectIdentifier) any { + if len(references) == 0 { + return unsetRequest.WithExternalAccessIntegrations(true) + } else { + return setRequest.WithExternalAccessIntegrations(references) + } + }) + } + return nil + }(), + ) + if err != nil { + return diag.FromErr(err) + } if updateParamDiags := handleProcedureParametersUpdate(d, setRequest, unsetRequest); len(updateParamDiags) > 0 { return updateParamDiags diff --git a/pkg/resources/procedure_java_acceptance_test.go b/pkg/resources/procedure_java_acceptance_test.go index 35bdd401ec..c6d0aba743 100644 --- a/pkg/resources/procedure_java_acceptance_test.go +++ b/pkg/resources/procedure_java_acceptance_test.go @@ -172,6 +172,27 @@ func TestAcc_ProcedureJava_InlineFull(t *testing.T) { stage, stageCleanup := acc.TestClient().Stage.CreateStage(t) t.Cleanup(stageCleanup) + secretId := acc.TestClient().Ids.RandomSchemaObjectIdentifier() + secretId2 := acc.TestClient().Ids.RandomSchemaObjectIdentifier() + + networkRule, networkRuleCleanup := acc.TestClient().NetworkRule.Create(t) + t.Cleanup(networkRuleCleanup) + + secret, secretCleanup := acc.TestClient().Secret.CreateWithGenericString(t, secretId, "test_secret_string") + t.Cleanup(secretCleanup) + + secret2, secret2Cleanup := acc.TestClient().Secret.CreateWithGenericString(t, secretId2, "test_secret_string_2") + t.Cleanup(secret2Cleanup) + + externalAccessIntegration, externalAccessIntegrationCleanup := acc.TestClient().ExternalAccessIntegration.CreateExternalAccessIntegrationWithNetworkRuleAndSecret(t, networkRule.ID(), secret.ID()) + t.Cleanup(externalAccessIntegrationCleanup) + + externalAccessIntegration2, externalAccessIntegration2Cleanup := acc.TestClient().ExternalAccessIntegration.CreateExternalAccessIntegrationWithNetworkRuleAndSecret(t, networkRule.ID(), secret2.ID()) + t.Cleanup(externalAccessIntegration2Cleanup) + + tmpJavaProcedure := acc.TestClient().CreateSampleJavaProcedureAndJarOnUserStage(t) + tmpJavaProcedure2 := acc.TestClient().CreateSampleJavaProcedureAndJarOnUserStage(t) + className := "TestFunc" funcName := "echoVarchar" argName := "x" @@ -186,8 +207,36 @@ func TestAcc_ProcedureJava_InlineFull(t *testing.T) { procedureModel := model.ProcedureJavaBasicInline("w", id, dataType, handler, definition). WithArgument(argName, dataType). + WithImports( + sdk.NormalizedPath{StageLocation: "~", PathOnStage: tmpJavaProcedure.JarName}, + sdk.NormalizedPath{StageLocation: "~", PathOnStage: tmpJavaProcedure2.JarName}, + ). + WithSnowparkPackage("1.14.0"). + WithPackages("com.snowflake:telemetry:0.1.0"). + WithExternalAccessIntegrations(externalAccessIntegration, externalAccessIntegration2). + WithSecrets(map[string]sdk.SchemaObjectIdentifier{ + "abc": secretId, + "def": secretId2, + }). + WithTargetPathParts(stage.ID().FullyQualifiedName(), jarName). + WithRuntimeVersion("11"). + WithComment("some comment") + + procedureModelUpdateWithoutRecreation := model.ProcedureJavaBasicInline("w", id, dataType, handler, definition). + WithArgument(argName, dataType). + WithImports( + sdk.NormalizedPath{StageLocation: "~", PathOnStage: tmpJavaProcedure.JarName}, + sdk.NormalizedPath{StageLocation: "~", PathOnStage: tmpJavaProcedure2.JarName}, + ). + WithSnowparkPackage("1.14.0"). + WithPackages("com.snowflake:telemetry:0.1.0"). + WithExternalAccessIntegrations(externalAccessIntegration). + WithSecrets(map[string]sdk.SchemaObjectIdentifier{ + "def": secretId2, + }). WithTargetPathParts(stage.ID().FullyQualifiedName(), jarName). - WithRuntimeVersion("11") + WithRuntimeVersion("11"). + WithComment("some other comment") resource.Test(t, resource.TestCase{ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, @@ -204,18 +253,52 @@ func TestAcc_ProcedureJava_InlineFull(t *testing.T) { resourceassert.ProcedureJavaResource(t, procedureModel.ResourceReference()). HasNameString(id.Name()). HasIsSecureString(r.BooleanDefault). - HasCommentString(sdk.DefaultProcedureComment). - HasImportsLength(0). + HasImportsLength(2). HasRuntimeVersionString("11"). HasProcedureDefinitionString(definition). + HasCommentString("some comment"). HasProcedureLanguageString("JAVA"). HasFullyQualifiedNameString(id.FullyQualifiedName()), assert.Check(resource.TestCheckResourceAttr(procedureModel.ResourceReference(), "target_path.0.stage_location", stage.ID().FullyQualifiedName())), assert.Check(resource.TestCheckResourceAttr(procedureModel.ResourceReference(), "target_path.0.path_on_stage", jarName)), + assert.Check(resource.TestCheckResourceAttr(procedureModel.ResourceReference(), "secrets.#", "2")), + assert.Check(resource.TestCheckResourceAttr(procedureModel.ResourceReference(), "external_access_integrations.#", "2")), + assert.Check(resource.TestCheckResourceAttr(procedureModel.ResourceReference(), "packages.#", "1")), + assert.Check(resource.TestCheckResourceAttr(procedureModel.ResourceReference(), "packages.0", "com.snowflake:telemetry:0.1.0")), resourceshowoutputassert.ProcedureShowOutput(t, procedureModel.ResourceReference()). HasIsSecure(false), ), }, + // UPDATE WITHOUT RECREATION + { + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(procedureModelUpdateWithoutRecreation.ResourceReference(), plancheck.ResourceActionUpdate), + }, + }, + Config: config.FromModels(t, procedureModelUpdateWithoutRecreation), + Check: assert.AssertThat(t, + resourceassert.ProcedureJavaResource(t, procedureModelUpdateWithoutRecreation.ResourceReference()). + HasNameString(id.Name()). + HasIsSecureString(r.BooleanDefault). + HasImportsLength(2). + HasRuntimeVersionString("11"). + HasProcedureDefinitionString(definition). + HasCommentString("some other comment"). + HasProcedureLanguageString("JAVA"). + HasFullyQualifiedNameString(id.FullyQualifiedName()), + assert.Check(resource.TestCheckResourceAttr(procedureModelUpdateWithoutRecreation.ResourceReference(), "target_path.0.stage_location", stage.ID().FullyQualifiedName())), + assert.Check(resource.TestCheckResourceAttr(procedureModelUpdateWithoutRecreation.ResourceReference(), "target_path.0.path_on_stage", jarName)), + assert.Check(resource.TestCheckResourceAttr(procedureModelUpdateWithoutRecreation.ResourceReference(), "secrets.#", "1")), + assert.Check(resource.TestCheckResourceAttr(procedureModelUpdateWithoutRecreation.ResourceReference(), "secrets.0.secret_variable_name", "def")), + assert.Check(resource.TestCheckResourceAttr(procedureModelUpdateWithoutRecreation.ResourceReference(), "secrets.0.secret_id", secretId2.FullyQualifiedName())), + assert.Check(resource.TestCheckResourceAttr(procedureModelUpdateWithoutRecreation.ResourceReference(), "external_access_integrations.#", "1")), + assert.Check(resource.TestCheckResourceAttr(procedureModelUpdateWithoutRecreation.ResourceReference(), "external_access_integrations.0", externalAccessIntegration.Name())), + assert.Check(resource.TestCheckResourceAttr(procedureModelUpdateWithoutRecreation.ResourceReference(), "packages.#", "1")), + resourceshowoutputassert.ProcedureShowOutput(t, procedureModelUpdateWithoutRecreation.ResourceReference()). + HasIsSecure(false), + ), + }, }, }) } diff --git a/pkg/sdk/procedures_ext.go b/pkg/sdk/procedures_ext.go index 59f2b2fbee..4a308dc97c 100644 --- a/pkg/sdk/procedures_ext.go +++ b/pkg/sdk/procedures_ext.go @@ -185,7 +185,6 @@ func procedureDetailsFromRows(rows []ProcedureDetail) (*ProcedureDetails, error) default: v.NormalizedPackages = []string{} } - } return v, errors.Join(errs...)