From b88a2510478fba98674a7cbdbb596716ea760b27 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 20 Mar 2024 10:28:05 +0100 Subject: [PATCH 1/7] Update docs for permissions sets for groups and tokens --- docs/resources/group.md | 29 ++++++++- docs/resources/service_token.md | 29 ++++++++- pkg/dbt_cloud/common.go | 78 +++++++++++++++++++++++ pkg/resources/group.go | 28 +------- pkg/resources/service_token.go | 28 +------- templates/resources/group.md.tmpl | 46 ++++++++++++- templates/resources/service_token.md.tmpl | 64 +++++++++++++++++++ 7 files changed, 242 insertions(+), 60 deletions(-) create mode 100644 templates/resources/service_token.md.tmpl diff --git a/docs/resources/group.md b/docs/resources/group.md index 47052b54..1cc1ff77 100644 --- a/docs/resources/group.md +++ b/docs/resources/group.md @@ -7,7 +7,34 @@ description: |- # dbtcloud_group (Resource) -*Note*: Groups currently do not support updates, as per both the API and the UI. +The mapping of permission names [from the docs](https://docs.getdbt.com/docs/cloud/manage-access/enterprise-permissions) to the permissions to set in Terraform is the following: + +|Permission name......... | Permission code| +|-- | --| +|Account Admin | account_admin| +|Account Viewer | account_viewer| +|Admin | admin| +|Analyst | analyst| +|Billing Admin | billing_admin| +|Database Admin | database_admin| +|Developer | developer| +|Git Admin | git_admin| +|Job Admin | job_admin| +|Job Runner | job_runner| +|Job Viewer | job_viewer| +|Member | member| +|Metadata Only | metadata_only| +|Owner | owner| +|Project Creator | project_creator| +|Read-Only | readonly| +|Security Admin | security_admin| +|Semantic Layer Only | semantic_layer_only| +|Stakeholder | stakeholder| +|Team Admin | team_admin| +|Webhooks Only | webhooks_only| + + + ## Example Usage diff --git a/docs/resources/service_token.md b/docs/resources/service_token.md index 3f668acd..2c0ae5f4 100644 --- a/docs/resources/service_token.md +++ b/docs/resources/service_token.md @@ -7,6 +7,32 @@ description: |- # dbtcloud_service_token (Resource) +The mapping of permission names [from the docs](https://docs.getdbt.com/docs/cloud/manage-access/enterprise-permissions) to the permissions to set in Terraform is the following: + +|Permission name......... | Permission code| +|-- | --| +|Account Admin | account_admin| +|Account Viewer | account_viewer| +|Admin | admin| +|Analyst | analyst| +|Billing Admin | billing_admin| +|Database Admin | database_admin| +|Developer | developer| +|Git Admin | git_admin| +|Job Admin | job_admin| +|Job Runner | job_runner| +|Job Viewer | job_viewer| +|Member | member| +|Metadata Only | metadata_only| +|Owner | owner| +|Project Creator | project_creator| +|Read-Only | readonly| +|Security Admin | security_admin| +|Semantic Layer Only | semantic_layer_only| +|Stakeholder | stakeholder| +|Team Admin | team_admin| +|Webhooks Only | webhooks_only| + @@ -29,9 +55,6 @@ resource "dbtcloud_service_token" "test_service_token" { project_id = dbtcloud_project.dbt_project.id } } - -// permission_set accepts one of the following values: -// "account_admin","admin","database_admin","git_admin","team_admin","job_admin","job_viewer","analyst","developer","stakeholder","readonly","project_creator","account_viewer","metadata_only" ``` diff --git a/pkg/dbt_cloud/common.go b/pkg/dbt_cloud/common.go index 413f6199..4bf52f2f 100644 --- a/pkg/dbt_cloud/common.go +++ b/pkg/dbt_cloud/common.go @@ -1,8 +1,86 @@ package dbt_cloud +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/samber/lo" +) + const ( STATE_ACTIVE = 1 STATE_DELETED = 2 ID_DELIMITER = ":" NUM_THREADS_CREDENTIAL = 6 ) + +var ( + PermissionSets = []string{ + "owner", + "member", + "account_admin", + "security_admin", + "billing_admin", + "admin", + "database_admin", + "git_admin", + "team_admin", + "job_admin", + "job_runner", + "job_viewer", + "analyst", + "developer", + "stakeholder", + "readonly", + "project_creator", + "account_viewer", + "metadata_only", + "semantic_layer_only", + "webhooks_only", + } +) + +// This is not used now but allows us to find the list of permission sets allowed +// Terraform doesn't allow to run it in the offline validation mode though as we don't have access to the configuration context +type ConstantsResponse struct { + Data Constants `json:"data"` + Status ResponseStatus `json:"status"` +} + +type Constants struct { + PermissionSets map[string]string `json:"permissions_sets"` +} + +func (c *Client) GetConstants() (*Constants, error) { + req, err := http.NewRequest( + "GET", + fmt.Sprintf("%s/v2/constants/", c.HostURL), + nil, + ) + if err != nil { + return nil, err + } + + body, err := c.doRequest(req) + if err != nil { + return nil, err + } + + constantsResponse := ConstantsResponse{} + err = json.Unmarshal(body, &constantsResponse) + if err != nil { + return nil, err + } + + return &constantsResponse.Data, nil +} + +func (c *Client) GetPermissionIDs() ([]string, error) { + constants, err := c.GetConstants() + if err != nil { + return nil, err + } + + return lo.Keys(constants.PermissionSets), nil +} diff --git a/pkg/resources/group.go b/pkg/resources/group.go index fe3c4160..b3fce898 100644 --- a/pkg/resources/group.go +++ b/pkg/resources/group.go @@ -11,32 +11,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) -var ( - permissionSets = []string{ - "owner", - "member", - "account_admin", - "security_admin", - "billing_admin", - "admin", - "database_admin", - "git_admin", - "team_admin", - "job_admin", - "job_runner", - "job_viewer", - "analyst", - "developer", - "stakeholder", - "readonly", - "project_creator", - "account_viewer", - "metadata_only", - "semantic_layer_only", - "webhooks_only", - } -) - func ResourceGroup() *schema.Resource { return &schema.Resource{ CreateContext: resourceGroupCreate, @@ -79,7 +53,7 @@ func ResourceGroup() *schema.Resource { Type: schema.TypeString, Required: true, Description: "Set of permissions to apply", - ValidateFunc: validation.StringInSlice(permissionSets, false), + ValidateFunc: validation.StringInSlice(dbt_cloud.PermissionSets, false), }, "project_id": { Type: schema.TypeInt, diff --git a/pkg/resources/service_token.go b/pkg/resources/service_token.go index a5b6b5fa..4a8f765e 100644 --- a/pkg/resources/service_token.go +++ b/pkg/resources/service_token.go @@ -11,32 +11,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) -var ( - servicetokenPermissionSets = []string{ - "owner", - "member", - "account_admin", - "security_admin", - "billing_admin", - "admin", - "database_admin", - "git_admin", - "team_admin", - "job_admin", - "job_runner", - "job_viewer", - "analyst", - "developer", - "stakeholder", - "readonly", - "project_creator", - "account_viewer", - "metadata_only", - "semantic_layer_only", - "webhooks_only", - } -) - func ResourceServiceToken() *schema.Resource { return &schema.Resource{ CreateContext: resourceServiceTokenCreate, @@ -79,7 +53,7 @@ func ResourceServiceToken() *schema.Resource { Required: true, Description: "Set of permissions to apply", ValidateFunc: validation.StringInSlice( - servicetokenPermissionSets, + dbt_cloud.PermissionSets, false, ), }, diff --git a/templates/resources/group.md.tmpl b/templates/resources/group.md.tmpl index 801e81a4..d6b268fa 100644 --- a/templates/resources/group.md.tmpl +++ b/templates/resources/group.md.tmpl @@ -1,22 +1,64 @@ --- -page_title: "{{.Name}} {{.Type}} - {{.RenderedProviderName}}" +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +{{ if gt (len (split .Description " --- ")) 1 -}} +subcategory: "{{ index (split .Description " --- ") 0 }}" +{{- else -}} subcategory: "" +{{- end }} description: |- +{{ if gt (len (split .Description " --- ")) 1 -}} +{{ index (split .Description " --- ") 1 | plainmarkdown | trimspace | prefixlines " " }} +{{- else -}} {{ .Description | plainmarkdown | trimspace | prefixlines " " }} +{{- end }} --- # {{.Name}} ({{.Type}}) -*Note*: Groups currently do not support updates, as per both the API and the UI. +The mapping of permission names [from the docs](https://docs.getdbt.com/docs/cloud/manage-access/enterprise-permissions) to the permissions to set in Terraform is the following: +|Permission name......... | Permission code| +|-- | --| +|Account Admin | account_admin| +|Account Viewer | account_viewer| +|Admin | admin| +|Analyst | analyst| +|Billing Admin | billing_admin| +|Database Admin | database_admin| +|Developer | developer| +|Git Admin | git_admin| +|Job Admin | job_admin| +|Job Runner | job_runner| +|Job Viewer | job_viewer| +|Member | member| +|Metadata Only | metadata_only| +|Owner | owner| +|Project Creator | project_creator| +|Read-Only | readonly| +|Security Admin | security_admin| +|Semantic Layer Only | semantic_layer_only| +|Stakeholder | stakeholder| +|Team Admin | team_admin| +|Webhooks Only | webhooks_only| + +{{ if gt (len (split .Description " --- ")) 1 -}} +{{ index (split .Description " --- ") 1 | trimspace }} +{{ else }} +{{ .Description | trimspace }} +{{- end }} + +{{ if .HasExample -}} ## Example Usage {{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} +{{- end }} {{ .SchemaMarkdown | trimspace }} +{{- if .HasImport }} ## Import Import is supported using the following syntax: {{ codefile "shell" (printf "%s%s%s" "examples/resources/" .Name "/import.sh") }} +{{- end }} diff --git a/templates/resources/service_token.md.tmpl b/templates/resources/service_token.md.tmpl new file mode 100644 index 00000000..d6b268fa --- /dev/null +++ b/templates/resources/service_token.md.tmpl @@ -0,0 +1,64 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +{{ if gt (len (split .Description " --- ")) 1 -}} +subcategory: "{{ index (split .Description " --- ") 0 }}" +{{- else -}} +subcategory: "" +{{- end }} +description: |- +{{ if gt (len (split .Description " --- ")) 1 -}} +{{ index (split .Description " --- ") 1 | plainmarkdown | trimspace | prefixlines " " }} +{{- else -}} +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +{{- end }} +--- + +# {{.Name}} ({{.Type}}) + +The mapping of permission names [from the docs](https://docs.getdbt.com/docs/cloud/manage-access/enterprise-permissions) to the permissions to set in Terraform is the following: + +|Permission name......... | Permission code| +|-- | --| +|Account Admin | account_admin| +|Account Viewer | account_viewer| +|Admin | admin| +|Analyst | analyst| +|Billing Admin | billing_admin| +|Database Admin | database_admin| +|Developer | developer| +|Git Admin | git_admin| +|Job Admin | job_admin| +|Job Runner | job_runner| +|Job Viewer | job_viewer| +|Member | member| +|Metadata Only | metadata_only| +|Owner | owner| +|Project Creator | project_creator| +|Read-Only | readonly| +|Security Admin | security_admin| +|Semantic Layer Only | semantic_layer_only| +|Stakeholder | stakeholder| +|Team Admin | team_admin| +|Webhooks Only | webhooks_only| + +{{ if gt (len (split .Description " --- ")) 1 -}} +{{ index (split .Description " --- ") 1 | trimspace }} +{{ else }} +{{ .Description | trimspace }} +{{- end }} + +{{ if .HasExample -}} +## Example Usage + +{{ tffile (printf "%s%s%s" "examples/resources/" .Name "/resource.tf") }} +{{- end }} + +{{ .SchemaMarkdown | trimspace }} +{{- if .HasImport }} + +## Import + +Import is supported using the following syntax: + +{{ codefile "shell" (printf "%s%s%s" "examples/resources/" .Name "/import.sh") }} +{{- end }} From ead7c2748afd688ccab6369331f6cf200fc991b7 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 20 Mar 2024 10:28:57 +0100 Subject: [PATCH 2/7] Update example for service token --- examples/resources/dbtcloud_service_token/resource.tf | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/resources/dbtcloud_service_token/resource.tf b/examples/resources/dbtcloud_service_token/resource.tf index 2d3ffdcb..1882005e 100644 --- a/examples/resources/dbtcloud_service_token/resource.tf +++ b/examples/resources/dbtcloud_service_token/resource.tf @@ -14,6 +14,3 @@ resource "dbtcloud_service_token" "test_service_token" { project_id = dbtcloud_project.dbt_project.id } } - -// permission_set accepts one of the following values: -// "account_admin","admin","database_admin","git_admin","team_admin","job_admin","job_viewer","analyst","developer","stakeholder","readonly","project_creator","account_viewer","metadata_only" From b3dbe6388440c75858a8db10b6bb1feed0b1a2a8 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 20 Mar 2024 10:30:24 +0100 Subject: [PATCH 3/7] Update docs for repo and project_repo --- docs/resources/project_repository.md | 4 ++-- docs/resources/repository.md | 6 ++++-- pkg/resources/project_repository.go | 19 ++++++++++++++++--- templates/resources/repository.md.tmpl | 6 ++++-- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/docs/resources/project_repository.md b/docs/resources/project_repository.md index a524333f..4fcd0956 100644 --- a/docs/resources/project_repository.md +++ b/docs/resources/project_repository.md @@ -2,13 +2,13 @@ page_title: "dbtcloud_project_repository Resource - dbtcloud" subcategory: "" description: |- - + This resource allows you to link a dbt Cloud project to a git repository. --- # dbtcloud_project_repository (Resource) - +This resource allows you to link a dbt Cloud project to a git repository. ## Example Usage diff --git a/docs/resources/repository.md b/docs/resources/repository.md index d580544e..f28f2c8e 100644 --- a/docs/resources/repository.md +++ b/docs/resources/repository.md @@ -7,8 +7,10 @@ description: |- # dbtcloud_repository (Resource) -*Note*: Some upstream resources can be slow to create, so if creating a project at -the same time as the repository, it's recommended to use the `depends_on` meta argument. +This resource allows you to manage connections to git repositories in dbt Cloud. + +By itself, this resource won't show you the repository in the dbt Cloud UI. +You will need to also set up a [`dbtcloud_project_repository` resource](https://registry.terraform.io/providers/dbt-labs/dbtcloud/latest/docs/resources/project_repository) as well to link your dbt Cloud project and the git repository. In order to find the `github_installation_id`, you can log in to dbt Cloud, replace `` by your dbt Cloud URL and run the following commands in the Google Chrome console: diff --git a/pkg/resources/project_repository.go b/pkg/resources/project_repository.go index 689a082b..bc9a2c16 100644 --- a/pkg/resources/project_repository.go +++ b/pkg/resources/project_repository.go @@ -36,10 +36,15 @@ func ResourceProjectRepository() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, + Description: "This resource allows you to link a dbt Cloud project to a git repository.", } } -func resourceProjectRepositoryCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceProjectRepositoryCreate( + ctx context.Context, + d *schema.ResourceData, + m interface{}, +) diag.Diagnostics { c := m.(*dbt_cloud.Client) var diags diag.Diagnostics @@ -67,7 +72,11 @@ func resourceProjectRepositoryCreate(ctx context.Context, d *schema.ResourceData return diags } -func resourceProjectRepositoryRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceProjectRepositoryRead( + ctx context.Context, + d *schema.ResourceData, + m interface{}, +) diag.Diagnostics { c := m.(*dbt_cloud.Client) var diags diag.Diagnostics @@ -97,7 +106,11 @@ func resourceProjectRepositoryRead(ctx context.Context, d *schema.ResourceData, return diags } -func resourceProjectRepositoryDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceProjectRepositoryDelete( + ctx context.Context, + d *schema.ResourceData, + m interface{}, +) diag.Diagnostics { c := m.(*dbt_cloud.Client) var diags diag.Diagnostics diff --git a/templates/resources/repository.md.tmpl b/templates/resources/repository.md.tmpl index 7e41ffcb..c0faa945 100644 --- a/templates/resources/repository.md.tmpl +++ b/templates/resources/repository.md.tmpl @@ -7,8 +7,10 @@ description: |- # {{.Name}} ({{.Type}}) -*Note*: Some upstream resources can be slow to create, so if creating a project at -the same time as the repository, it's recommended to use the `depends_on` meta argument. +This resource allows you to manage connections to git repositories in dbt Cloud. + +By itself, this resource won't show you the repository in the dbt Cloud UI. +You will need to also set up a [`dbtcloud_project_repository` resource](https://registry.terraform.io/providers/dbt-labs/dbtcloud/latest/docs/resources/project_repository) as well to link your dbt Cloud project and the git repository. In order to find the `github_installation_id`, you can log in to dbt Cloud, replace `` by your dbt Cloud URL and run the following commands in the Google Chrome console: From 8dd04bc92dd147b0e6a0eb2530554ef9933c52f1 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 20 Mar 2024 10:31:31 +0100 Subject: [PATCH 4/7] Update Diff for extended attributes to allow JSON strings --- pkg/resources/extended_attributes.go | 47 +++++++-- .../extended_attributes_acceptance_test.go | 97 ++++++++++++++----- 2 files changed, 113 insertions(+), 31 deletions(-) diff --git a/pkg/resources/extended_attributes.go b/pkg/resources/extended_attributes.go index cd103e12..0075be48 100644 --- a/pkg/resources/extended_attributes.go +++ b/pkg/resources/extended_attributes.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "reflect" "strconv" "strings" @@ -40,6 +41,16 @@ func ResourceExtendedAttributes() *schema.Resource { Type: schema.TypeString, Required: true, Description: "A JSON string listing the extended attributes mapping. The keys are the connections attributes available in the `profiles.yml` for a given adapter. Any fields entered will override connection details or credentials set on the environment or project. To avoid incorrect Terraform diffs, it is recommended to create this string using `jsonencode` in your Terraform code. (see example)", + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + var oldJSON, newJSON map[string]interface{} + if err := json.Unmarshal([]byte(old), &oldJSON); err != nil { + return false + } + if err := json.Unmarshal([]byte(new), &newJSON); err != nil { + return false + } + return reflect.DeepEqual(oldJSON, newJSON) + }, }, }, @@ -51,7 +62,11 @@ func ResourceExtendedAttributes() *schema.Resource { } } -func resourceExtendedAttributesCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceExtendedAttributesCreate( + ctx context.Context, + d *schema.ResourceData, + m interface{}, +) diag.Diagnostics { c := m.(*dbt_cloud.Client) var diags diag.Diagnostics @@ -66,14 +81,25 @@ func resourceExtendedAttributesCreate(ctx context.Context, d *schema.ResourceDat return diag.FromErr(err) } - d.SetId(fmt.Sprintf("%d%s%d", extendedAttributes.ProjectID, dbt_cloud.ID_DELIMITER, *extendedAttributes.ID)) + d.SetId( + fmt.Sprintf( + "%d%s%d", + extendedAttributes.ProjectID, + dbt_cloud.ID_DELIMITER, + *extendedAttributes.ID, + ), + ) resourceExtendedAttributesRead(ctx, d, m) return diags } -func resourceExtendedAttributesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceExtendedAttributesRead( + ctx context.Context, + d *schema.ResourceData, + m interface{}, +) diag.Diagnostics { c := m.(*dbt_cloud.Client) var diags diag.Diagnostics @@ -98,7 +124,6 @@ func resourceExtendedAttributesRead(ctx context.Context, d *schema.ResourceData, } if err := d.Set("extended_attributes_id", &extendedAttributes.ID); err != nil { - // return diag.FromErr(fmt.Errorf("BPER: %s", &extendedAttributes.ID)) return diag.FromErr(err) } if err := d.Set("state", extendedAttributes.State); err != nil { @@ -131,7 +156,11 @@ func resourceExtendedAttributesRead(ctx context.Context, d *schema.ResourceData, // return !reflect.DeepEqual(objOld, objNew) // } -func resourceExtendedAttributesUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceExtendedAttributesUpdate( + ctx context.Context, + d *schema.ResourceData, + m interface{}, +) diag.Diagnostics { c := m.(*dbt_cloud.Client) projectId, err := strconv.Atoi(strings.Split(d.Id(), dbt_cloud.ID_DELIMITER)[0]) @@ -148,7 +177,7 @@ func resourceExtendedAttributesUpdate(ctx context.Context, d *schema.ResourceDat if d.HasChange("state") || d.HasChange("project_id") || - d.HasChange("extended_attributes") { //BPER - update logic here + d.HasChange("extended_attributes") { extendedAttributes, err := c.GetExtendedAttributes(projectId, extendedAttributesId) if err != nil { @@ -177,7 +206,11 @@ func resourceExtendedAttributesUpdate(ctx context.Context, d *schema.ResourceDat return resourceExtendedAttributesRead(ctx, d, m) } -func resourceExtendedAttributesDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +func resourceExtendedAttributesDelete( + ctx context.Context, + d *schema.ResourceData, + m interface{}, +) diag.Diagnostics { c := m.(*dbt_cloud.Client) var diags diag.Diagnostics diff --git a/pkg/resources/extended_attributes_acceptance_test.go b/pkg/resources/extended_attributes_acceptance_test.go index da4eec79..c2176280 100644 --- a/pkg/resources/extended_attributes_acceptance_test.go +++ b/pkg/resources/extended_attributes_acceptance_test.go @@ -26,33 +26,78 @@ func TestAccDbtCloudExtendedAttributesResource(t *testing.T) { { Config: testAccDbtCloudExtendedAttributesResourceConfig(projectName, "step1"), Check: resource.ComposeTestCheckFunc( - testAccCheckDbtCloudExtendedAttributesExists("dbtcloud_extended_attributes.test_extended_attributes"), - resource.TestCheckResourceAttrSet("dbtcloud_extended_attributes.test_extended_attributes", "extended_attributes_id"), - resource.TestCheckResourceAttrSet("dbtcloud_extended_attributes.test_extended_attributes", "project_id"), - resource.TestCheckResourceAttrSet("dbtcloud_extended_attributes.test_extended_attributes", "extended_attributes"), - resource.TestCheckResourceAttr("dbtcloud_extended_attributes.test_extended_attributes", "extended_attributes", "{\"catalog\":\"dbt_catalog\",\"http_path\":\"/sql/your/http/path\",\"my_nested_field\":{\"subfield\":\"my_value\"},\"type\":\"databricks\"}"), + testAccCheckDbtCloudExtendedAttributesExists( + "dbtcloud_extended_attributes.test_extended_attributes", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_extended_attributes.test_extended_attributes", + "extended_attributes_id", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_extended_attributes.test_extended_attributes", + "project_id", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_extended_attributes.test_extended_attributes", + "extended_attributes", + ), + resource.TestCheckResourceAttr( + "dbtcloud_extended_attributes.test_extended_attributes", + "extended_attributes", + "{\"catalog\":\"dbt_catalog\",\"http_path\":\"/sql/your/http/path\",\"my_nested_field\":{\"subfield\":\"my_value\"},\"type\":\"databricks\"}", + ), ), }, // MODIFY { Config: testAccDbtCloudExtendedAttributesResourceConfig(projectName, "step2"), Check: resource.ComposeTestCheckFunc( - testAccCheckDbtCloudExtendedAttributesExists("dbtcloud_extended_attributes.test_extended_attributes"), - resource.TestCheckResourceAttrSet("dbtcloud_extended_attributes.test_extended_attributes", "extended_attributes_id"), - resource.TestCheckResourceAttrSet("dbtcloud_extended_attributes.test_extended_attributes", "project_id"), - resource.TestCheckResourceAttrSet("dbtcloud_extended_attributes.test_extended_attributes", "extended_attributes"), - resource.TestCheckResourceAttr("dbtcloud_extended_attributes.test_extended_attributes", "extended_attributes", "{\"catalog\":\"dbt_catalog_new\",\"type\":\"databricks\"}"), + testAccCheckDbtCloudExtendedAttributesExists( + "dbtcloud_extended_attributes.test_extended_attributes", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_extended_attributes.test_extended_attributes", + "extended_attributes_id", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_extended_attributes.test_extended_attributes", + "project_id", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_extended_attributes.test_extended_attributes", + "extended_attributes", + ), + resource.TestCheckResourceAttr( + "dbtcloud_extended_attributes.test_extended_attributes", + "extended_attributes", + "{\"catalog\":\"dbt_catalog_new\",\"type\":\"databricks\"}", + ), ), }, // REMOVE FROM ENVIRONMENT { Config: testAccDbtCloudExtendedAttributesResourceUnlinked(projectName), Check: resource.ComposeTestCheckFunc( - testAccCheckDbtCloudExtendedAttributesExists("dbtcloud_extended_attributes.test_extended_attributes"), - resource.TestCheckResourceAttrSet("dbtcloud_extended_attributes.test_extended_attributes", "extended_attributes_id"), - resource.TestCheckResourceAttrSet("dbtcloud_extended_attributes.test_extended_attributes", "project_id"), - resource.TestCheckResourceAttrSet("dbtcloud_extended_attributes.test_extended_attributes", "extended_attributes"), - resource.TestCheckResourceAttr("dbtcloud_extended_attributes.test_extended_attributes", "extended_attributes", "{\"catalog\":\"dbt_catalog_new\",\"type\":\"databricks\"}"), + testAccCheckDbtCloudExtendedAttributesExists( + "dbtcloud_extended_attributes.test_extended_attributes", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_extended_attributes.test_extended_attributes", + "extended_attributes_id", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_extended_attributes.test_extended_attributes", + "project_id", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_extended_attributes.test_extended_attributes", + "extended_attributes", + ), + resource.TestCheckResourceAttr( + "dbtcloud_extended_attributes.test_extended_attributes", + "extended_attributes", + "{\"catalog\":\"dbt_catalog_new\",\"type\":\"databricks\"}", + ), ), }, // IMPORT @@ -83,13 +128,13 @@ func testAccDbtCloudExtendedAttributesResourceConfig(projectName, step string) s ) ` } else if step == "step2" { - extendedAttributes = `jsonencode( - { - type = "databricks" - catalog = "dbt_catalog_new" - } - ) - ` + // try the "Heredoc" syntax instead of the jsonencode function + extendedAttributes = `< Date: Wed, 20 Mar 2024 10:34:09 +0100 Subject: [PATCH 5/7] Update logic for custom_branch_only and remove it from multiple tests --- docs/resources/job.md | 10 +-- examples/resources/dbtcloud_job/resource.tf | 3 - pkg/data_sources/job_acceptance_test.go | 1 - .../notification_acceptance_test.go | 18 ++++- pkg/dbt_cloud/job.go | 6 -- pkg/resources/job.go | 15 ++-- pkg/resources/job_acceptance_test.go | 19 +++-- pkg/resources/notification_acceptance_test.go | 75 ++++++++++++++----- .../project_artefacts_acceptance_test.go | 15 +++- pkg/resources/webhook_acceptance_test.go | 69 +++++++++++++---- templates/resources/job.md.tmpl | 5 -- 11 files changed, 158 insertions(+), 78 deletions(-) diff --git a/docs/resources/job.md b/docs/resources/job.md index dc00ff2b..b2cbba0b 100644 --- a/docs/resources/job.md +++ b/docs/resources/job.md @@ -13,11 +13,6 @@ description: |- Those improvements include modifications to deferral which was historically set at the job level and will now be set at the environment level. Deferral can still be set to "self" by setting `self_deferring` to `true` but with the new approach, deferral to other runs need to be done with `deferring_environment_id` instead of `deferring_job_id`. -~> As of beginning of February 2024, job chaining with `job_completion_trigger_condition` is in private beta and not available to all users. -
-
-This notice will be removed once the feature is generally available. - ## Example Usage @@ -41,7 +36,6 @@ resource "dbtcloud_job" "daily_job" { run_generate_sources = true target_name = "default" triggers = { - "custom_branch_only" : false, "github_webhook" : false, "git_provider_webhook" : false, "schedule" : true @@ -67,7 +61,6 @@ resource "dbtcloud_job" "ci_job" { project_id = dbtcloud_project.dbt_project.id run_generate_sources = false triggers = { - "custom_branch_only" : true, "github_webhook" : true, "git_provider_webhook" : true, "schedule" : false @@ -91,7 +84,6 @@ resource "dbtcloud_job" "downstream_job" { project_id = dbtcloud_project.dbt_project2.id run_generate_sources = true triggers = { - "custom_branch_only" : false, "github_webhook" : false, "git_provider_webhook" : false, "schedule" : false @@ -115,7 +107,7 @@ resource "dbtcloud_job" "downstream_job" { - `execute_steps` (List of String) List of commands to execute for the job - `name` (String) Job name - `project_id` (Number) Project ID to create the job in -- `triggers` (Map of Boolean) Flags for which types of triggers to use, the values are `github_webhook`, `git_provider_webhook`, `schedule` and `custom_branch_only`.
`custom_branch_only` is only relevant for CI jobs triggered automatically on PR creation to only trigger a job on a PR to the custom branch of the environment. To create a job in a 'deactivated' state, set all to `false`. +- `triggers` (Map of Boolean) Flags for which types of triggers to use, the values are `github_webhook`, `git_provider_webhook`, and `schedule`.
`custom_branch_only` used to be allowed but has been deprecated from the API. The jobs will use the custom branch of the environment. Please remove the `custom_branch_only` from your config.
To create a job in a 'deactivated' state, set all to `false`. ### Optional diff --git a/examples/resources/dbtcloud_job/resource.tf b/examples/resources/dbtcloud_job/resource.tf index c0f237f6..d457ee94 100644 --- a/examples/resources/dbtcloud_job/resource.tf +++ b/examples/resources/dbtcloud_job/resource.tf @@ -17,7 +17,6 @@ resource "dbtcloud_job" "daily_job" { run_generate_sources = true target_name = "default" triggers = { - "custom_branch_only" : false, "github_webhook" : false, "git_provider_webhook" : false, "schedule" : true @@ -43,7 +42,6 @@ resource "dbtcloud_job" "ci_job" { project_id = dbtcloud_project.dbt_project.id run_generate_sources = false triggers = { - "custom_branch_only" : true, "github_webhook" : true, "git_provider_webhook" : true, "schedule" : false @@ -67,7 +65,6 @@ resource "dbtcloud_job" "downstream_job" { project_id = dbtcloud_project.dbt_project2.id run_generate_sources = true triggers = { - "custom_branch_only" : false, "github_webhook" : false, "git_provider_webhook" : false, "schedule" : false diff --git a/pkg/data_sources/job_acceptance_test.go b/pkg/data_sources/job_acceptance_test.go index 23fa1620..b8eee00f 100644 --- a/pkg/data_sources/job_acceptance_test.go +++ b/pkg/data_sources/job_acceptance_test.go @@ -60,7 +60,6 @@ func jobs(jobName string) string { "dbt run" ] triggers = { - "custom_branch_only" : false, "github_webhook" : false, "schedule" : false, "git_provider_webhook": false diff --git a/pkg/data_sources/notification_acceptance_test.go b/pkg/data_sources/notification_acceptance_test.go index bb993d96..ed215754 100644 --- a/pkg/data_sources/notification_acceptance_test.go +++ b/pkg/data_sources/notification_acceptance_test.go @@ -15,9 +15,20 @@ func TestAccDbtCloudNotificationDataSource(t *testing.T) { config := notification(randomProjectName) check := resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("data.dbtcloud_notification.test_notification_external", "notification_type", "4"), - resource.TestCheckResourceAttrSet("data.dbtcloud_notification.test_notification_external", "on_failure.0"), - resource.TestCheckResourceAttr("data.dbtcloud_notification.test_notification_external", "external_email", "nomail@mail.com"), + resource.TestCheckResourceAttr( + "data.dbtcloud_notification.test_notification_external", + "notification_type", + "4", + ), + resource.TestCheckResourceAttrSet( + "data.dbtcloud_notification.test_notification_external", + "on_failure.0", + ), + resource.TestCheckResourceAttr( + "data.dbtcloud_notification.test_notification_external", + "external_email", + "nomail@mail.com", + ), ) resource.ParallelTest(t, resource.TestCase{ @@ -55,7 +66,6 @@ func notification(projectName string) string { "github_webhook" : false, "git_provider_webhook" : false, "schedule" : false, - "custom_branch_only" : false, } } diff --git a/pkg/dbt_cloud/job.go b/pkg/dbt_cloud/job.go index 10c91a08..f8ab9e2b 100644 --- a/pkg/dbt_cloud/job.go +++ b/pkg/dbt_cloud/job.go @@ -11,7 +11,6 @@ import ( type JobTrigger struct { Github_Webhook bool `json:"github_webhook"` Schedule bool `json:"schedule"` - Custom_Branch_Only bool `json:"custom_branch_only"` GitProviderWebhook bool `json:"git_provider_webhook"` } @@ -140,10 +139,6 @@ func (c *Client) CreateJob( if !s_found { schedule = false } - custom_branch_only, cbo_found := triggers["custom_branch_only"] - if !cbo_found { - custom_branch_only = false - } git_provider_webhook, gpw_found := triggers["git_provider_webhook"] if !gpw_found { git_provider_webhook = false @@ -151,7 +146,6 @@ func (c *Client) CreateJob( jobTriggers := JobTrigger{ Github_Webhook: github_webhook.(bool), Schedule: schedule.(bool), - Custom_Branch_Only: custom_branch_only.(bool), GitProviderWebhook: git_provider_webhook.(bool), } jobSettings := JobSettings{ diff --git a/pkg/resources/job.go b/pkg/resources/job.go index 73a7fc27..14651483 100644 --- a/pkg/resources/job.go +++ b/pkg/resources/job.go @@ -73,7 +73,7 @@ var jobSchema = map[string]*schema.Schema{ Optional: false, Default: false, }, - Description: "Flags for which types of triggers to use, the values are `github_webhook`, `git_provider_webhook`, `schedule` and `custom_branch_only`.
`custom_branch_only` is only relevant for CI jobs triggered automatically on PR creation to only trigger a job on a PR to the custom branch of the environment. To create a job in a 'deactivated' state, set all to `false`.", + Description: "Flags for which types of triggers to use, the values are `github_webhook`, `git_provider_webhook`, and `schedule`.
`custom_branch_only` used to be allowed but has been deprecated from the API. The jobs will use the custom branch of the environment. Please remove the `custom_branch_only` from your config.
To create a job in a 'deactivated' state, set all to `false`.", }, "num_threads": &schema.Schema{ Type: schema.TypeInt, @@ -302,6 +302,15 @@ func resourceJobRead(ctx context.Context, d *schema.ResourceData, m interface{}) var triggers map[string]interface{} triggersInput, _ := json.Marshal(job.Triggers) json.Unmarshal(triggersInput, &triggers) + + // for now, we allow people to keep the triggers.custom_branch_only config even if the parameter was deprecated in the API + // we set the state to the current config value, so it doesn't do anything + listedTriggers := d.Get("triggers").(map[string]interface{}) + listedCustomBranchOnly, ok := listedTriggers["custom_branch_only"].(bool) + if ok { + triggers["custom_branch_only"] = listedCustomBranchOnly + } + if err := d.Set("triggers", triggers); err != nil { return diag.FromErr(err) } @@ -521,10 +530,6 @@ func resourceJobUpdate( if !ok { return diag.FromErr(fmt.Errorf("schedule was not provided")) } - job.Triggers.Custom_Branch_Only, ok = newTriggers["custom_branch_only"].(bool) - if !ok { - return diag.FromErr(fmt.Errorf("custom_branch_only was not provided")) - } } if d.HasChange("schedule_type") { scheduleType := d.Get("schedule_type").(string) diff --git a/pkg/resources/job_acceptance_test.go b/pkg/resources/job_acceptance_test.go index 51aff216..2468af55 100644 --- a/pkg/resources/job_acceptance_test.go +++ b/pkg/resources/job_acceptance_test.go @@ -176,10 +176,14 @@ func TestAccDbtCloudJobResource(t *testing.T) { }, // IMPORT { - ResourceName: "dbtcloud_job.test_job", - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{}, + ResourceName: "dbtcloud_job.test_job", + ImportState: true, + ImportStateVerify: true, + // we don't check triggers.custom_branch_only as we currently allow people to keep triggers.custom_branch_only in their config to not break peopple's Terraform project + ImportStateVerifyIgnore: []string{ + "triggers.%", + "triggers.custom_branch_only", + }, }, }, }) @@ -209,7 +213,6 @@ resource "dbtcloud_job" "test_job" { "github_webhook": false, "git_provider_webhook": false, "schedule": false, - "custom_branch_only": false, } } `, projectName, environmentName, DBT_CLOUD_VERSION, jobName) @@ -295,7 +298,7 @@ resource "dbtcloud_job" "test_job" { "github_webhook": false, "git_provider_webhook": false, "schedule": true, - "custom_branch_only": false, + "custom_branch_only": true, } is_active = true num_threads = 37 @@ -318,7 +321,6 @@ resource "dbtcloud_job" "test_job_4" { "github_webhook": false, "git_provider_webhook": false, "schedule": false, - "custom_branch_only": false, } job_completion_trigger_condition { job_id = dbtcloud_job.test_job.id @@ -365,7 +367,6 @@ resource "dbtcloud_job" "test_job" { "github_webhook": false, "git_provider_webhook": false, "schedule": true, - "custom_branch_only": false, } is_active = true num_threads = 37 @@ -388,7 +389,6 @@ resource "dbtcloud_job" "test_job_2" { "github_webhook": false, "git_provider_webhook": false, "schedule": false, - "custom_branch_only": false, } %s } @@ -404,7 +404,6 @@ resource "dbtcloud_job" "test_job_3" { "github_webhook": false, "git_provider_webhook": false, "schedule": false, - "custom_branch_only": false, } %s } diff --git a/pkg/resources/notification_acceptance_test.go b/pkg/resources/notification_acceptance_test.go index 23ec7dc8..56710c07 100644 --- a/pkg/resources/notification_acceptance_test.go +++ b/pkg/resources/notification_acceptance_test.go @@ -24,28 +24,69 @@ func TestAccDbtCloudNotificationResource(t *testing.T) { { Config: testAccDbtCloudNotificationResourceCreateNotifications(projectName), Check: resource.ComposeTestCheckFunc( - testAccCheckDbtCloudNotificationExists("dbtcloud_notification.test_notification_internal"), - resource.TestCheckResourceAttr("dbtcloud_notification.test_notification_internal", "notification_type", "1"), - resource.TestCheckResourceAttrSet("dbtcloud_notification.test_notification_internal", "on_success.0"), - resource.TestCheckResourceAttrSet("dbtcloud_notification.test_notification_internal", "on_cancel.0"), - resource.TestCheckResourceAttrSet("dbtcloud_notification.test_notification_internal", "on_cancel.1"), - resource.TestCheckResourceAttrSet("dbtcloud_notification.test_notification_internal", "on_failure.0"), - - testAccCheckDbtCloudNotificationExists("dbtcloud_notification.test_notification_external"), - resource.TestCheckResourceAttr("dbtcloud_notification.test_notification_external", "notification_type", "4"), - resource.TestCheckResourceAttrSet("dbtcloud_notification.test_notification_external", "on_failure.0"), - resource.TestCheckResourceAttr("dbtcloud_notification.test_notification_external", "external_email", "nomail@mail.com"), + testAccCheckDbtCloudNotificationExists( + "dbtcloud_notification.test_notification_internal", + ), + resource.TestCheckResourceAttr( + "dbtcloud_notification.test_notification_internal", + "notification_type", + "1", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_notification.test_notification_internal", + "on_success.0", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_notification.test_notification_internal", + "on_cancel.0", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_notification.test_notification_internal", + "on_cancel.1", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_notification.test_notification_internal", + "on_failure.0", + ), + + testAccCheckDbtCloudNotificationExists( + "dbtcloud_notification.test_notification_external", + ), + resource.TestCheckResourceAttr( + "dbtcloud_notification.test_notification_external", + "notification_type", + "4", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_notification.test_notification_external", + "on_failure.0", + ), + resource.TestCheckResourceAttr( + "dbtcloud_notification.test_notification_external", + "external_email", + "nomail@mail.com", + ), ), }, // MODIFY { Config: testAccDbtCloudNotificationResourceModifyNotifications(projectName), Check: resource.ComposeTestCheckFunc( - testAccCheckDbtCloudNotificationExists("dbtcloud_notification.test_notification_internal"), - resource.TestCheckNoResourceAttr("dbtcloud_notification.test_notification_internal", "on_cancel.0"), - - testAccCheckDbtCloudNotificationExists("dbtcloud_notification.test_notification_external"), - resource.TestCheckResourceAttrSet("dbtcloud_notification.test_notification_external", "on_cancel.0"), + testAccCheckDbtCloudNotificationExists( + "dbtcloud_notification.test_notification_internal", + ), + resource.TestCheckNoResourceAttr( + "dbtcloud_notification.test_notification_internal", + "on_cancel.0", + ), + + testAccCheckDbtCloudNotificationExists( + "dbtcloud_notification.test_notification_external", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_notification.test_notification_external", + "on_cancel.0", + ), ), }, // IMPORT @@ -89,7 +130,6 @@ resource "dbtcloud_job" "test_notification_job_1" { "github_webhook" : false, "git_provider_webhook" : false, "schedule" : false, - "custom_branch_only" : false, } } @@ -104,7 +144,6 @@ resource "dbtcloud_job" "test_notification_job_2" { "github_webhook" : false, "git_provider_webhook" : false, "schedule" : false, - "custom_branch_only" : false, } } `, projectName, DBT_CLOUD_VERSION) diff --git a/pkg/resources/project_artefacts_acceptance_test.go b/pkg/resources/project_artefacts_acceptance_test.go index ce69fcd9..f54bd36e 100644 --- a/pkg/resources/project_artefacts_acceptance_test.go +++ b/pkg/resources/project_artefacts_acceptance_test.go @@ -24,9 +24,15 @@ func TestAccDbtCloudProjectArtefactsResource(t *testing.T) { CheckDestroy: testAccCheckDbtCloudProjectArtefactsDestroy, Steps: []resource.TestStep{ { - Config: testAccDbtCloudProjectArtefactsResourceBasicConfig(projectName, environmentName, jobName), + Config: testAccDbtCloudProjectArtefactsResourceBasicConfig( + projectName, + environmentName, + jobName, + ), Check: resource.ComposeTestCheckFunc( - testAccCheckDbtCloudProjectArtefactsExists("dbtcloud_project_artefacts.test_project_artefacts"), + testAccCheckDbtCloudProjectArtefactsExists( + "dbtcloud_project_artefacts.test_project_artefacts", + ), ), }, // IMPORT @@ -47,7 +53,9 @@ func TestAccDbtCloudProjectArtefactsResource(t *testing.T) { }) } -func testAccDbtCloudProjectArtefactsResourceBasicConfig(projectName, environmentName, jobName string) string { +func testAccDbtCloudProjectArtefactsResourceBasicConfig( + projectName, environmentName, jobName string, +) string { return fmt.Sprintf(` resource "dbtcloud_project" "test_artefacts_project" { name = "%s" @@ -71,7 +79,6 @@ resource "dbtcloud_job" "test_job" { "github_webhook": false, "git_provider_webhook": false, "schedule": false, - "custom_branch_only": false, } run_generate_sources = true generate_docs = true diff --git a/pkg/resources/webhook_acceptance_test.go b/pkg/resources/webhook_acceptance_test.go index 14371232..fec3a039 100644 --- a/pkg/resources/webhook_acceptance_test.go +++ b/pkg/resources/webhook_acceptance_test.go @@ -26,12 +26,34 @@ func TestAccDbtCloudWebhookResource(t *testing.T) { Config: testAccDbtCloudWebhookResourceBasicConfig(webhookName, projectName), Check: resource.ComposeTestCheckFunc( testAccCheckDbtCloudWebhookExists("dbtcloud_webhook.test_webhook"), - resource.TestCheckResourceAttr("dbtcloud_webhook.test_webhook", "name", webhookName), - resource.TestCheckResourceAttrSet("dbtcloud_webhook.test_webhook", "hmac_secret"), - resource.TestCheckResourceAttrSet("dbtcloud_webhook.test_webhook", "account_identifier"), - resource.TestCheckResourceAttr("dbtcloud_webhook.test_webhook", "event_types.#", "2"), - resource.TestCheckResourceAttr("dbtcloud_webhook.test_webhook", "job_ids.#", "0"), - resource.TestCheckResourceAttr("dbtcloud_webhook.test_webhook", "client_url", "http://localhost/nothing"), + resource.TestCheckResourceAttr( + "dbtcloud_webhook.test_webhook", + "name", + webhookName, + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_webhook.test_webhook", + "hmac_secret", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_webhook.test_webhook", + "account_identifier", + ), + resource.TestCheckResourceAttr( + "dbtcloud_webhook.test_webhook", + "event_types.#", + "2", + ), + resource.TestCheckResourceAttr( + "dbtcloud_webhook.test_webhook", + "job_ids.#", + "0", + ), + resource.TestCheckResourceAttr( + "dbtcloud_webhook.test_webhook", + "client_url", + "http://localhost/nothing", + ), ), }, // MODIFY @@ -39,12 +61,34 @@ func TestAccDbtCloudWebhookResource(t *testing.T) { Config: testAccDbtCloudWebhookResourceFullConfig(webhookName2, projectName), Check: resource.ComposeTestCheckFunc( testAccCheckDbtCloudWebhookExists("dbtcloud_webhook.test_webhook"), - resource.TestCheckResourceAttr("dbtcloud_webhook.test_webhook", "name", webhookName2), - resource.TestCheckResourceAttrSet("dbtcloud_webhook.test_webhook", "hmac_secret"), - resource.TestCheckResourceAttrSet("dbtcloud_webhook.test_webhook", "account_identifier"), - resource.TestCheckResourceAttr("dbtcloud_webhook.test_webhook", "event_types.#", "1"), - resource.TestCheckResourceAttr("dbtcloud_webhook.test_webhook", "job_ids.#", "1"), - resource.TestCheckResourceAttr("dbtcloud_webhook.test_webhook", "client_url", "http://localhost/new-nothing"), + resource.TestCheckResourceAttr( + "dbtcloud_webhook.test_webhook", + "name", + webhookName2, + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_webhook.test_webhook", + "hmac_secret", + ), + resource.TestCheckResourceAttrSet( + "dbtcloud_webhook.test_webhook", + "account_identifier", + ), + resource.TestCheckResourceAttr( + "dbtcloud_webhook.test_webhook", + "event_types.#", + "1", + ), + resource.TestCheckResourceAttr( + "dbtcloud_webhook.test_webhook", + "job_ids.#", + "1", + ), + resource.TestCheckResourceAttr( + "dbtcloud_webhook.test_webhook", + "client_url", + "http://localhost/new-nothing", + ), ), }, // IMPORT @@ -101,7 +145,6 @@ resource "dbtcloud_job" "test" { run_generate_sources = false target_name = "default" triggers = { - "custom_branch_only" : false, "github_webhook" : false, "git_provider_webhook" : false, "schedule" : false diff --git a/templates/resources/job.md.tmpl b/templates/resources/job.md.tmpl index e3539417..bb728416 100644 --- a/templates/resources/job.md.tmpl +++ b/templates/resources/job.md.tmpl @@ -13,11 +13,6 @@ description: |- Those improvements include modifications to deferral which was historically set at the job level and will now be set at the environment level. Deferral can still be set to "self" by setting `self_deferring` to `true` but with the new approach, deferral to other runs need to be done with `deferring_environment_id` instead of `deferring_job_id`. -~> As of beginning of February 2024, job chaining with `job_completion_trigger_condition` is in private beta and not available to all users. -
-
-This notice will be removed once the feature is generally available. - ## Example Usage From ea8336c37c991cf2ee13b21d4549dc481a0b05b5 Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 20 Mar 2024 10:34:41 +0100 Subject: [PATCH 6/7] Update env_vars to recreate resources following changes in the API --- pkg/resources/environment_variable.go | 68 ++----------------- ...t_variable_job_override_acceptance_test.go | 1 - 2 files changed, 4 insertions(+), 65 deletions(-) diff --git a/pkg/resources/environment_variable.go b/pkg/resources/environment_variable.go index f5e55c71..70a7fb61 100644 --- a/pkg/resources/environment_variable.go +++ b/pkg/resources/environment_variable.go @@ -8,7 +8,6 @@ import ( "github.com/dbt-labs/terraform-provider-dbtcloud/pkg/dbt_cloud" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -16,7 +15,6 @@ func ResourceEnvironmentVariable() *schema.Resource { return &schema.Resource{ CreateContext: resourceEnvironmentVariableCreate, ReadContext: resourceEnvironmentVariableRead, - UpdateContext: resourceEnvironmentVariableUpdate, DeleteContext: resourceEnvironmentVariableDelete, Schema: map[string]*schema.Schema{ @@ -24,6 +22,7 @@ func ResourceEnvironmentVariable() *schema.Resource { Type: schema.TypeInt, Required: true, Description: "Project for the variable to be created in", + ForceNew: true, }, "name": &schema.Schema{ Type: schema.TypeString, @@ -36,7 +35,7 @@ func ResourceEnvironmentVariable() *schema.Resource { if !(strings.HasPrefix(v, "DBT_")) { errs = append( errs, - fmt.Errorf("The env var must start with DBT_ , got: %s", v), + fmt.Errorf("the env var must start with DBT_ , got: %s", v), ) } return @@ -46,29 +45,11 @@ func ResourceEnvironmentVariable() *schema.Resource { Type: schema.TypeMap, Required: true, Description: "Map from environment names to respective variable value, a special key `project` should be set for the project default variable value. This field is not set as sensitive so take precautions when using secret environment variables.", + // since the last change in the API we can't just PUSH the new values, so, we can delete it and then create it again + ForceNew: true, }, }, - CustomizeDiff: customdiff.All( - customdiff.ForceNewIfChange( - "environment_values", - func(ctx context.Context, old, new, meta any) bool { - // if any key has been removed, we have to recreate the env var - oldMap := old.(map[string]any) - newMap := new.(map[string]any) - - for key := range oldMap { - if _, exists := newMap[key]; !exists { - // Key from old is not present in new - return true - } - } - - return false - }, - ), - ), - Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, @@ -159,47 +140,6 @@ func resourceEnvironmentVariableRead( return diags } -func resourceEnvironmentVariableUpdate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - c := m.(*dbt_cloud.Client) - - projectID, err := strconv.Atoi(strings.Split(d.Id(), dbt_cloud.ID_DELIMITER)[0]) - if err != nil { - return diag.FromErr(err) - } - - environmentVariableName := strings.Split(d.Id(), dbt_cloud.ID_DELIMITER)[1] - if err != nil { - return diag.FromErr(err) - } - - if d.HasChange("environment_values") { - environmentVariable, err := c.GetEnvironmentVariable(projectID, environmentVariableName) - if err != nil { - return diag.FromErr(err) - } - - if d.HasChange("environment_values") { - environmentValues := d.Get("environment_values").(map[string]interface{}) - environmentValuesStrings := make(map[string]string) - for envName, value := range environmentValues { - environmentValuesStrings[envName] = value.(string) - } - environmentVariable.EnvironmentNameValues = environmentValuesStrings - } - - _, err = c.UpdateEnvironmentVariable(projectID, *environmentVariable) - if err != nil { - return diag.FromErr(err) - } - } - - return resourceEnvironmentVariableRead(ctx, d, m) -} - func resourceEnvironmentVariableDelete( ctx context.Context, d *schema.ResourceData, diff --git a/pkg/resources/environment_variable_job_override_acceptance_test.go b/pkg/resources/environment_variable_job_override_acceptance_test.go index b0b71200..cc8b5e10 100644 --- a/pkg/resources/environment_variable_job_override_acceptance_test.go +++ b/pkg/resources/environment_variable_job_override_acceptance_test.go @@ -141,7 +141,6 @@ resource dbtcloud_job test_job_sched { name = "%s" project_id = dbtcloud_project.test_project.id triggers = { - "custom_branch_only" : false, "github_webhook" : false, "git_provider_webhook" : false, "schedule" : false From 740d0d4bbb6e4ff8cc7cdf7dd092e815a7de91ac Mon Sep 17 00:00:00 2001 From: Benoit Perigaud <8754100+b-per@users.noreply.github.com> Date: Wed, 20 Mar 2024 10:34:54 +0100 Subject: [PATCH 7/7] Update Changelog --- CHANGELOG.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67aa155a..06a81582 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,20 @@ All notable changes to this project will be documented in this file. -## [Unreleased](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.2.21...HEAD) +## [Unreleased](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.2.22...HEAD) + +## [0.2.22](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.2.21...v0.2.22) + +## Changes + +- [#240](https://github.com/dbt-labs/terraform-provider-dbtcloud/issues/240) Add notice of deprecation for `triggers.custom_branch_only` for jobs and update logic to make it work even though people have it to true or false in their config. We might raise an error if the field is still there in the future. +- Update diff calculation for Extended Attributes, allowing strings which are not set with `jsonencode()` +- [#241](https://github.com/dbt-labs/terraform-provider-dbtcloud/issues/241) Force recreation of env vars when values change to work with the recent changes in the dbt Cloud API + +## Documentation + +- Add list of permission names and permission codes in the docs of the `service_token` and `group` +- Add info in `dbtcloud_repository` about the need to also create a `dbtcloud_project_repository` ## [0.2.21](https://github.com/dbt-labs/terraform-provider-dbtcloud/compare/v0.2.20...v0.2.21)